StripExtension

Share your advanced PureBasic knowledge/code with the community.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

StripExtension

Post 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
Last edited by Mistrel on Fri Apr 08, 2011 9:10 am, edited 1 time in total.
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post 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
SFSxOI
Addict
Addict
Posts: 2970
Joined: Sat Dec 31, 2005 5:24 pm
Location: Where ya would never look.....

Post by SFSxOI »

Hey, I was just looking for something like this, how timely. Thank You :)
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post 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)
Last edited by Hroudtwolf on Fri Jan 25, 2008 1:33 am, edited 1 time in total.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post by Mistrel »

Why would my code run slowly, Hroudtwolf?
User avatar
Hroudtwolf
Addict
Addict
Posts: 803
Joined: Sat Feb 12, 2005 3:35 am
Location: Germany(Hessen)
Contact:

Post by Hroudtwolf »

Test it by yourself ;-)
But it isn't important for such function.
It's just fun to optimize it.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post 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")
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post 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)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
AND51
Addict
Addict
Posts: 1040
Joined: Sun Oct 15, 2006 8:56 pm
Location: Germany
Contact:

Post by AND51 »

@ StripExtension1
Len (sFilename) * SizeOf (tCHAR) = StringByteLength() :wink:

@ StripExtension, StripExtension1 and StripExtension2
:arrow: 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
PB 4.30

Code: Select all

onErrorGoto(?Fred)
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post 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")
:)
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Thalius
Enthusiast
Enthusiast
Posts: 711
Joined: Thu Jul 17, 2003 4:15 pm
Contact:

Post 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
"In 3D there is never enough Time to do Things right,
but there's always enough Time to make them *look* right."
"psssst! i steal signatures... don't tell anyone! ;)"
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Post 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. :)
Post Reply