RightString code working for Unicode and ASCII?

Just starting out? Need help? Post your questions and find answers here.
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

RightString code working for Unicode and ASCII?

Post 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")
User avatar
Demivec
Addict
Addict
Posts: 4259
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: RightString code working for Unicode and ASCII?

Post 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
Vitor_Boss®
User
User
Posts: 81
Joined: Thu Sep 23, 2010 4:22 am

Re: RightString code working for Unicode and ASCII?

Post 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")
Sorry by bad English.
HP Pavilion DV6-2155DX: Intel i3-330m 2.13 / 4GB DDR3 / 500GB Sata2 HD / Display 15.6" LED / Win7 Ultimate x64 / PB 4.50 x86 demo.
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Re: RightString code working for Unicode and ASCII?

Post 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 :oops:
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
Fred
Administrator
Administrator
Posts: 18153
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: RightString code working for Unicode and ASCII?

Post 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
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: RightString code working for Unicode and ASCII?

Post by Trond »

As a replacement for #PB_Compiler_Unicode you can use SizeOf(Character). It's shorter as well.
User avatar
charvista
Addict
Addict
Posts: 949
Joined: Tue Sep 23, 2008 11:38 pm
Location: Belgium

Re: RightString code working for Unicode and ASCII?

Post 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. :shock:
Should the constants always be verified at startup? such as If #True <> 1 then show a Warning, #True has changed! :?:
- Windows 11 Home 64-bit
- PureBasic 6.10 LTS (x64)
- 64 Gb RAM
- 13th Gen Intel(R) Core(TM) i9-13900K 3.00 GHz
- 5K monitor with DPI @ 200%
Fred
Administrator
Administrator
Posts: 18153
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: RightString code working for Unicode and ASCII?

Post 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.
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: RightString code working for Unicode and ASCII?

Post 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? :cry:
I would like to have programmatic access to the list of available constants.
Then, there are no surprises. :wink:
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Fred
Administrator
Administrator
Posts: 18153
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: RightString code working for Unicode and ASCII?

Post by Fred »

:?:
User avatar
HeX0R
Addict
Addict
Posts: 1187
Joined: Mon Sep 20, 2004 7:12 am
Location: Hell

Re: RightString code working for Unicode and ASCII?

Post 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")
eesau
Enthusiast
Enthusiast
Posts: 589
Joined: Fri Apr 27, 2007 12:38 pm
Location: Finland

Re: RightString code working for Unicode and ASCII?

Post 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? :cry:
I would like to have programmatic access to the list of available constants.
Then, there are no surprises. :wink:
Tools -> Structure Viewer -> Constants?

Granted, the "Structure Viewer" is misleading since you can view interfaces and constants as well. Maybe it needs a renaming.
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: RightString code working for Unicode and ASCII?

Post by skywalk »

skywalk wrote:I would like to have programmatic access to the list of available constants.
:wink:
@eesau, Thanks, but I want my PB Tool code to browse the constants. The Structure Viewer is only a peep hole. :(
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
Michael Vogel
Addict
Addict
Posts: 2797
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: RightString code working for Unicode and ASCII?

Post by Michael Vogel »

Thanks for all postings :wink:

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
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: RightString code working for Unicode and ASCII?

Post by Trond »

SizeOf() is a compile-time function, it doesn't affect execution time.
Post Reply