Page 1 of 2
RightString code working for Unicode and ASCII?
Posted: Wed Feb 09, 2011 5:47 pm
by Michael Vogel
I'm using the following code which extracts the rightmost directory of a path string independendly if a backslash is at the end or not works with ASCII but fails with Unicode, what's wrong?!
Code: Select all
Procedure.s GetRightMost(s.s)
Protected n
n=Len(s)-1
If n>=0
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
s=Left(s,n)
EndIf
While n
n-1<<#PB_Compiler_Unicode
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
ProcedureReturn Mid(s,n+2)
EndIf
Wend
EndIf
ProcedureReturn s
EndProcedure
Debug GetRightMost("\abc\def\ghi\")
Debug GetRightMost("\abc\def\ghi")
Re: RightString code working for Unicode and ASCII?
Posted: Wed Feb 09, 2011 6:05 pm
by Demivec
I'm still looking at your code, in the meantime this version might be helpful:
Code: Select all
Procedure.s GetRightMost(s.s)
Protected n = CountString(s, "\")
If Right(s, 1) <> "\"
n + 1
EndIf
ProcedureReturn StringField(s, n, "\")
EndProcedure
@Edit: In your procedure you are using 'n' to count both characters and bytes. This is fine in ascii (1 char = 1 byte) but not unicode (1 char = 2 bytes). This occurs in more than one place in the procedure:
Code: Select all
Procedure.s GetRightMost(s.s)
Protected n
n=Len(s)-1 ;not correct for unicode
If n>=0
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
s=Left(s,n)
EndIf
While n
n-1<<#PB_Compiler_Unicode
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
ProcedureReturn Mid(s,n+2) ;not correct for unicode
EndIf
Wend
EndIf
ProcedureReturn s
EndProcedure
Re: RightString code working for Unicode and ASCII?
Posted: Wed Feb 09, 2011 6:36 pm
by Vitor_BossĀ®
Worked for me on both mode this way:
Code: Select all
Procedure.s GetRightMost(s.s)
Protected n
n=Len(s)-1
If n>=0
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
s=Left(s,n)
EndIf
While n > 0
n-1
If PeekC(@s+n) = '\'
ProcedureReturn Mid(s, n+2)
EndIf
Wend
EndIf
ProcedureReturn s
EndProcedure
Debug GetRightMost("\abc\def\ghi\")
Debug GetRightMost("\abc\def\ghi")
Re: RightString code working for Unicode and ASCII?
Posted: Wed Feb 09, 2011 6:56 pm
by ts-soft
a bit complicate
Code: Select all
Procedure.s GetRightMost(s.s)
If Right(s, 1) <> "\" : s + "\" : EndIf
ProcedureReturn StringField(s, CountString(s, "\"), "\")
EndProcedure
Debug GetRightMost("\abc\def\ghi\")
Debug GetRightMost("\abc\def\ghi")
oh, i see Demivec have posted the same

Re: RightString code working for Unicode and ASCII?
Posted: Thu Feb 10, 2011 10:34 am
by Fred
If PeekC(@s+n<<#PB_Compiler_Unicode)='\'
Never use a constant in an expression as you can't predict its value ! We can change it to another number without notice. Also, it can change depending of the OS
Re: RightString code working for Unicode and ASCII?
Posted: Thu Feb 10, 2011 11:46 am
by Trond
As a replacement for #PB_Compiler_Unicode you can use SizeOf(Character). It's shorter as well.
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 8:03 am
by charvista
Fred wrote:
Never use a constant in an expression as you can't predict its value !
Like the constant #True could become -1 instead of 1 as well.

Should the constants always be verified at startup? such as If #True <> 1 then show a Warning, #True has changed!

Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 9:49 am
by Fred
We try to don't change the constant value, but it can happen, so don't rely on it. The whole purpose of the constant is to hide the underlying number.
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 5:24 pm
by skywalk
Fred wrote:The whole purpose of the constant is to hide the underlying number.
That is understood, but do you have to be so good at hiding the actual Constants?
I would like to have programmatic access to the list of available constants.
Then, there are no surprises.

Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 6:05 pm
by Fred
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 6:22 pm
by HeX0R
I would do it like this:
Code: Select all
Procedure.s GetRightMost(s.s)
Protected *C.CHARACTER, i, Result.s
If Right(s, 1) = "\"
s = Left(s, Len(s) - 1)
EndIf
*C = @s + StringByteLength(s) - SizeOf(CHARACTER)
i = Len(s)
While *C >= @s
If *C\c = '\'
Result = Mid(s, i + 1)
Break
EndIf
*C - SizeOf(CHARACTER)
i - 1
Wend
ProcedureReturn Result
EndProcedure
Debug GetRightMost("\abc\def\ghi\")
Debug GetRightMost("\abc\def\ghi")
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 6:31 pm
by eesau
skywalk wrote:Fred wrote:The whole purpose of the constant is to hide the underlying number.
That is understood, but do you have to be so good at hiding the actual Constants?
I would like to have programmatic access to the list of available constants.
Then, there are no surprises.

Tools -> Structure Viewer -> Constants?
Granted, the "Structure Viewer" is misleading since you can view interfaces and constants as well. Maybe it needs a renaming.
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 6:48 pm
by skywalk
skywalk wrote:I would like to have
programmatic access to the list of available constants.

@eesau, Thanks, but I want my PB Tool code to browse the constants. The Structure Viewer is only a peep hole.

Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 8:41 pm
by Michael Vogel
Thanks for
all postings
Michael
The only excuse for my coding and especially the use of the (not so constant) constant is, that the SizeOf function may costs execution time because it will be calculated each time
Re: RightString code working for Unicode and ASCII?
Posted: Fri Feb 11, 2011 8:47 pm
by Trond
SizeOf() is a compile-time function, it doesn't affect execution time.