Page 1 of 1
StripExtension
Posted: Fri Jan 25, 2008 12:40 am
by Mistrel
This one is pretty self-explanatory.
Code: Select all
Procedure.s StripExtension(Filename.s)
For i=Len(Filename.s) To 1 Step -1
If mid(Filename.s,i,1)="."
ProcedureReturn Left(Filename.s,i-1)
EndIf
Next i
ProcedureReturn Filename.s
EndProcedure
Debug StripExtension("This.ext")
End
Posted: Fri Jan 25, 2008 1:00 am
by Hroudtwolf
Hi. Nice idea.
But it is possible that your code is a little bit slowly.
Maybe my try could be faster.
But I didn't made speedtests.
Code: Select all
; PureBasic-Lounge.com
; Author: Hroudtwolf
; OS: Windows, Linux, OSX
; Demo: Yes
Structure tCHAR
StructureUnion
c.c
s.s {1}
EndStructureUnion
EndStructure
Procedure.s StripExtension (sFilename.s)
Protected *Source.tCHAR = @sFilename + (Len (sFilename) * SizeOf (tCHAR))
Protected *EOS = @sFilename
Protected lFlag = #False
Protected sTemp .s
If Not *EOS : ProcedureReturn "" : EndIf
While *EOS <= *Source
If *Source\c = 46 And Not lFlag
lFlag = #True
*Source - SizeOf (tCHAR)
EndIf
If lFlag
sTemp = *Source\s + sTemp
EndIf
*Source - SizeOf (tCHAR)
Wend
ProcedureReturn sTemp
EndProcedure
; Safety. Only the extensions will be cutted.
Debug StripExtension("This.ext.ext")
Debug StripExtension(".This.ext.ext")
Debug StripExtension("This.ext")
Best regards
Wolf
Posted: Fri Jan 25, 2008 1:13 am
by SFSxOI
Hey, I was just looking for something like this, how timely. Thank You

Posted: Fri Jan 25, 2008 1:32 am
by Hroudtwolf
Faster one.
Code: Select all
; PureBasic-Lounge.com
; Author: Hroudtwolf
; OS: Windows, Linux, OSX
; Demo: Yes
Structure tCHAR
StructureUnion
c.c
s.s {1}
EndStructureUnion
EndStructure
Procedure.s StripExtension (sFilename.s)
Protected *Source.tCHAR = @sFilename + (Len (sFilename) * SizeOf (tCHAR))
Protected *EOS = @sFilename
If Not *EOS : ProcedureReturn "" : EndIf
While *EOS <= *Source
If *Source\c = 46
ProcedureReturn PeekS (*EOS , *Source - *EOS)
EndIf
*Source - SizeOf (tCHAR)
Wend
ProcedureReturn ""
EndProcedure
Test
Code: Select all
Structure tCHAR
StructureUnion
c.c
s.s {1}
EndStructureUnion
EndStructure
Procedure.s StripExtension1 (sFilename.s)
Protected *Source.tCHAR = @sFilename + (Len (sFilename) * SizeOf (tCHAR))
Protected *EOS = @sFilename
If Not *EOS : ProcedureReturn "" : EndIf
While *EOS <= *Source
If *Source\c = 46
ProcedureReturn PeekS (*EOS , *Source - *EOS)
EndIf
*Source - SizeOf (tCHAR)
Wend
ProcedureReturn ""
EndProcedure
Procedure.s StripExtension2 (sFilename.s)
For i=Len(sFilename.s) To 1 Step -1
If Mid(sFilename.s,i,1)="."
ProcedureReturn Left(sFilename.s,i-1)
EndIf
Next i
ProcedureReturn sFilename.s
EndProcedure
Define.s sTest
Define.l lTime1
Define.l lTime2
lTime1 = timeGetTime_()
For lI = 1 To 800000
sTest = StripExtension1 ("Filename.extension")
Next lI
lTime1 = timeGetTime_() - lTime1
lTime2 = timeGetTime_()
For lI = 1 To 800000
sTest = StripExtension2 ("Filename.extension")
Next lI
lTime2 = timeGetTime_() - lTime2
MessageBox_(0 , "StripExtension1 (MS):" + Str (lTime1) + #LF$ + "StripExtension2 (MS):" + Str (lTime2), "Test" , #MB_OK)
Posted: Fri Jan 25, 2008 1:32 am
by Mistrel
Why would my code run slowly, Hroudtwolf?
Posted: Fri Jan 25, 2008 1:33 am
by Hroudtwolf
Test it by yourself

But it isn't important for such function.
It's just fun to optimize it.
Posted: Fri Jan 25, 2008 10:37 am
by PB
My version (don't know how fast it is compared to the others, because
I'm far too lazy to cut-and-paste the other examples to test):
Code: Select all
Procedure.s StripExt(file$)
e$=GetExtensionPart(file$) : If e$ : e=1 : EndIf
ProcedureReturn Left(file$,Len(file$)-Len(e$)-e)
EndProcedure
Debug StripExt("iexplore.exe")
Debug StripExt("noextension")
Posted: Fri Jan 25, 2008 10:52 am
by PB
Okay, I added mine to the test and it comes second, which I think is a
good compromise between code size and speed.
BTW, a file called "file.name.ext" only has one extension, called "ext".
It's only the part from the final dot that is the actual extension.
Code: Select all
DisableDebugger
Structure tCHAR
StructureUnion
c.c
s.s {1}
EndStructureUnion
EndStructure
Procedure.s StripExtension1 (sFilename.s)
Protected *Source.tCHAR = @sFilename + (Len (sFilename) * SizeOf (tCHAR))
Protected *EOS = @sFilename
If Not *EOS : ProcedureReturn "" : EndIf
While *EOS <= *Source
If *Source\c = 46
ProcedureReturn PeekS (*EOS , *Source - *EOS)
EndIf
*Source - SizeOf (tCHAR)
Wend
ProcedureReturn ""
EndProcedure
Procedure.s StripExtension2 (sFilename.s)
For i=Len(sFilename.s) To 1 Step -1
If Mid(sFilename.s,i,1)="."
ProcedureReturn Left(sFilename.s,i-1)
EndIf
Next i
ProcedureReturn sFilename.s
EndProcedure
Procedure.s StripExt(file$)
e$=GetExtensionPart(file$) : If e$ : e=1 : EndIf
ProcedureReturn Left(file$,Len(file$)-Len(e$)-e)
EndProcedure
Define.s sTest
Define.l lTime1
Define.l lTime2
lTime1 = timeGetTime_()
For lI = 1 To 800000
sTest = StripExtension1 ("Filename.extension")
Next lI
lTime1 = timeGetTime_() - lTime1
lTime2 = timeGetTime_()
For lI = 1 To 800000
sTest = StripExtension2 ("Filename.extension")
Next lI
lTime2 = timeGetTime_() - lTime2
lTime3 = timeGetTime_()
For lI = 1 To 800000
sTest = StripExt ("Filename.extension")
Next lI
lTime3 = timeGetTime_() - lTime3
MessageBox_(0 , "StripExtension1 (MS):" + Str (lTime1) + #LF$ + "StripExtension2 (MS):" + Str (lTime2) + #LF$ + "StripExtension3 (MS):" + Str (lTime3), "Test" , #MB_OK)
Posted: Fri Jan 25, 2008 1:45 pm
by AND51
@ StripExtension1
Len (sFilename) * SizeOf (tCHAR) =
StringByteLength()
@ StripExtension, StripExtension1 and StripExtension2

Your codes fail when you feed your procedures with "C:\Folder with
.dot\no extension"
In a loop with 800000 loops, my procedure is ca. 29 ms slower than StripExtension1 (which is still the fastest),
but it can handle full paths. remember that Linux ("/") and Windows ("\") are using different path-separators, so my procedure is cross-platform compatible.
Code: Select all
Procedure.s myStripExtension(filename$)
Protected *dot.Character=@filename$+StringByteLength(filename$)-SizeOf(Character)
While *dot\c
If *dot\c = '\' Or *dot\c = '/'
ProcedureReturn filename$
ElseIf *dot\c = '.'
ProcedureReturn PeekS(@filename$, *dot-@filename$)
EndIf
*dot-SizeOf(Character)
Wend
ProcedureReturn filename$
EndProcedure
800 000 loops:
StripExtension1: 439 ms
myStripExtenstion: 468 ms
Posted: Fri Jan 25, 2008 11:10 pm
by Psychophanta
My 1.5 cents:
Code: Select all
Macro ReplaceFilenameExtension(filename,newfilenameextension="")
ReplaceString(filename#,"."+GetExtensionPart(filename#),newfilenameextension#,1,Len(filename#)-Len("."+GetExtensionPart(filename#)))
EndMacro
Debug ReplaceFilenameExtension("iexplore.exe")
Debug ReplaceFilenameExtension("noextension")
Debug ReplaceFilenameExtension("iexplore.exeeee.exeee.exe")
Debug ReplaceFilenameExtension("iexplore.exe.exeeee")

Posted: Sat Jan 26, 2008 12:13 am
by Thalius
Mistrel wrote:Why would my code run slowly, Hroudtwolf?
i could imagine because of Len and Mid which iterate thru the stringbuffer til the end then you step back backwards and reiterate. So working once len is known with a pointer than reMidding the string in a loop is alot faster.
Thalius
Posted: Sat Jan 26, 2008 4:24 am
by Mistrel
Thalius wrote:Mistrel wrote:Why would my code run slowly, Hroudtwolf?
i could imagine because of Len and Mid which iterate thru the stringbuffer til the end then you step back backwards and reiterate. So working once len is known with a pointer than reMidding the string in a loop is alot faster.
Thalius
Thank you.
