Page 1 of 2

API way to add backslash to a path

Posted: Sat Jan 27, 2007 7:38 am
by PB
For years I've been doing this to add a backslash to a path, because I didn't
know the Windows API could do it for me. The good thing is that the API won't
add a slash if it's already there, so you don't need to do an If/EndIf test. :)

Code: Select all

p1$="c:"
If Right(p1$,1)<>"\" : p1$+"\" : EndIf
Debug p1$

p2$="c:"
PathAddBackslash_(p2$)
Debug p2$

Posted: Sat Jan 27, 2007 12:26 pm
by Kaeru Gaman
because the length of code doesn't always determine performance, i did a speed-test... ;)

Code: Select all

time1 = ElapsedMilliseconds()
For n=0 To 9999999
  p1$="c:" 
  If Right(p1$,1)<>"\" : p1$+"\" : EndIf 
Next
time1 = ElapsedMilliseconds() - time1

time2 = ElapsedMilliseconds()
For n=0 To 9999999
  p2$="c:" 
  PathAddBackslash_(p2$) 
Next
time2 = ElapsedMilliseconds() - time2

MessageRequester("speed test", "String-Operation: " + Str(time1) + #CRLF$ + "API-Call: " + Str(time2) )
surprisingly, the API is twice as fast, with Unicode activated even three times as fast.

...guess it's the Right()-operation, that needs that much time...

Posted: Sat Jan 27, 2007 12:39 pm
by netmaestro
Thanks Peebs, nice tip! I didn't know about this little gem.

Posted: Sat Jan 27, 2007 1:51 pm
by Heathen
Cool man, thanks :)

Posted: Sat Jan 27, 2007 2:10 pm
by freak
You are making the string longer without reallocating it.
It works with such a short example, because windows allocates memory at a certain boundary (16 bytes iirc).
If you happen to have a string that exactly fills the allocated buffer, well... boom ;)

The chance for that is remote, but if it ever happens, good luck on tracing that bug...

Posted: Sat Jan 27, 2007 2:46 pm
by PB
> If you happen to have a string that exactly fills the allocated buffer, well... boom ;)

Are you sure? The MSDN docs says the return value will be null if the backslash
could not be appended due to inadequate buffer size, which means no boom?

Posted: Sat Jan 27, 2007 7:12 pm
by Psychophanta
Thanks PB,
Seems to work fine (upto 256 file name characters), look:

Code: Select all

For t=0 To 270
  p2$=LSet("c:",t,"n")
  Debug Right(p2$,3)
  Debug Len(p2$)
  PathAddBackslash_(p2$)
  Debug Right(p2$,3)
  Debug Len(p2$)
Next
The way winapi manages strings is the same as C and also the same way as PureBasic do, or am i wrong? So I'd bet Timo is wrong for the first time
:)

Posted: Sat Jan 27, 2007 8:04 pm
by freak
PB wrote:> If you happen to have a string that exactly fills the allocated buffer, well... boom ;)

Are you sure? The MSDN docs says the return value will be null if the backslash
could not be appended due to inadequate buffer size, which means no boom?
It also says that the buffer should be MAX_PATH in size, which is not the case.
As the function takes no "size" parameter it cannot know how big the buffer really is,
so my guess is it simply assumes MAX_PATH as the size.

And no, PB's string management is very different ;)

Posted: Sat Jan 27, 2007 10:42 pm
by SFSxOI
OK, i'm confused here; The MSDN site says: "lpszPath
[in, out] Pointer to a buffer with a string that represents a path. The size of this buffer should be set to MAX_PATH to ensure that it is large enough to hold the returned string."

So this means if a buffer size was MAX_PATH it would always be big enough to hold the returned string? So if PathAddBackslash_(p2$) and
p2$ was a pointer to a buffer that was MAX_PATH in size then there wouldn't be any problem? Are are you saying that a pointer to the buffer that was MAX_PATH wouldn't matter that there would still be problems because the function doesn't take a size parameter?

Posted: Sat Jan 27, 2007 11:04 pm
by Trond
No if the buffer has length MAX_PATH then there wouldn't be any BOOM. But if the buffer is shorter there will be BOOM since there is no size parameter. Alternatively, turn down your loudspeakers. *Straight face*

Posted: Sun Jan 28, 2007 12:27 am
by freak
Trond wrote:No if the buffer has length MAX_PATH then there wouldn't be any BOOM. But if the buffer is shorter there will be BOOM since there is no size parameter. Alternatively, turn down your loudspeakers. *Straight face*
Right, but there is no garantee for that with a PB string.

Posted: Sun Jan 28, 2007 12:43 am
by PB
So after all this, is it safer just to use If/EndIf to add a slash after all?
(And I love how BOOM is used now to indicate a crash; it's funny).

Posted: Sun Jan 28, 2007 12:57 am
by Joakim Christiansen
BOOM!
So after all this, is it safer just to use If/EndIf to add a slash after all?
Yeah, why not, if speed is not very important then go with it.

Posted: Sun Jan 28, 2007 4:57 pm
by remi_meier
Why not simply use
path.s{#MAX_PATH}
for your path variables??

Re: API way to add backslash to a path

Posted: Fri Jan 20, 2012 12:07 pm
by dobro



Declare PathAddBackslash(Path)

a$ = "c:\Kcc"
PathAddBackslash(@a$) ; la soluce qui tue : o)
debug a$
calldebugger

a$ = "c:\toto\"
PathAddBackslash(@a$) ; la soluce qui tue : o)
debug a$
calldebugger

procedure PathAddBackslash(Path )
     ;Solution By Dobro patented copyrighté Supra Hadopi : o)
     ; ajoute un "\" si pas present a la fin
    mem=Path
    path$= reversestring ( peeks (mem))
     if mid (Path$,1,1) <> "\"
        Path$= "\" +Path$
        Path$= reversestring (Path$)
         pokes (mem,path$)
     endif
endprocedure

;
; EPb