Author Topic: Correct way to compare strings?  (Read 2723 times)

0 Members and 1 Guest are viewing this topic.

Arnold

  • Guest
Correct way to compare strings?
« on: April 09, 2015, 06:20:49 AM »
Hi Charles,

I am about to create a small app which needs comparing strings and I am not sure if I am doing something wrong. This similar code shows my problem:

Code: OxygenBasic
  1. ' Compare strings in array
  2.  
  3. include "$\inc\console.inc"
  4. include "$\inc\MathMisc.inc"
  5.  
  6. indexbase 1
  7.  
  8. dim as string Lines[100]={32}
  9.  
  10. int lastline=countof lines
  11. int length
  12.  
  13. 'fill array randomly
  14. for x=1 to lastline
  15.     length=abs(rnd()*5) +5
  16.     lines[x]=""
  17.     for l=1 to length
  18.        lines[x]&=chr(abs(rnd()*48)+60)
  19.     next l
  20.     print lines[x] cr
  21. next x
  22.  
  23. print"Enter to continue ..." cr cr: waitkey()
  24.  
  25. lines[10]="_Sue"
  26. lines[90]="_Tom"
  27.  
  28. for x=1 to LastLine
  29. //   if (lines[x]="_Tom") or (lines[x]="_Sue") then  'does not work
  30.   if len(lines[x])=4 and (instr("_Tom", lines[x]) or instr("_Sue", lines[x])) then
  31.        print lines[x] " found in line " x " ... Enter" cr: waitkey()
  32.    else      
  33.        lines[x] = "Line " x " = " lines[x] : print lines[x] " ok " cr    
  34.    end if
  35. next x
  36.  
  37. print "Enter to end ..."
  38. waitkey()
  39.  

The code runs ok. But if I use in the last for .. loop the commented line instead of the next line then the program crashes at about record 14. Is using '=' (or '>', '<' etc) not legal in combination with strings?

Roland

Arnold

  • Guest
Re: Correct way to compare strings?
« Reply #1 on: April 09, 2015, 07:16:38 AM »
Using your code with comparestr I tried to build a function:

Code: OxygenBasic
  1. function compare_string(string a,b)
  2. int result
  3.  
  4. comparestr(a,b)
  5. (
  6.   jnz exit
  7.   ; strings are equal
  8.   result=0
  9.   jmp fwd ncompare
  10. )
  11. (
  12.   jg exit
  13.   ; string 2 is less
  14.   result=-1
  15.   jmp fwd ncompare
  16. )
  17. (
  18.   jl exit
  19.   ; string 2 is greater
  20.   result=1
  21.   jmp fwd ncompare
  22. )
  23. .ncompare
  24.  
  25. return result
  26. end function
  27.  

If I use in the for loop:
Code: OxygenBasic
  1.    if compare_string(lines[x],"_Sue")=0 or compare_string(lines[x],"_Tom")=0 then
  2.  

then the program will work too.


Charles Pegge

  • Guest
Re: Correct way to compare strings?
« Reply #2 on: April 09, 2015, 07:32:40 AM »
Roland,

Something nasty affecting compound string logic.

For now, there is a simple workaround, using a mini-function to handle the string comparison:

   sys is(string s){if s=lines(x){return 1}}

   if is("_Tom") or is("_Sue") then

Code: OxygenBasic
  1. includepath "$\inc\"
  2. include "console.inc"
  3. include "MathMisc.inc"
  4.  
  5. indexbase 1
  6.  
  7. dim as string Lines[100]={32}
  8.  
  9. int lastline=countof lines
  10. int length
  11.  
  12. 'fill array randomly
  13. for x=1 to lastline
  14.     length=abs(rnd()*5) +5
  15.     lines[x]=""
  16.     for l=1 to length
  17.        lines[x]&=chr(abs(rnd()*48)+60)
  18.     next l
  19.     print lines[x] cr
  20. next x
  21.  
  22. print"Enter to continue ..." cr cr: waitkey()
  23.  
  24. lines[10]="_Sue"
  25. lines[90]="_Tom"
  26.  
  27. for x=1 to LastLine
  28.    sys is(string s){if s=lines(x){return 1}}
  29.    if is("_Tom") or is("_Sue") then
  30.        print lines[x] " found in line " x " ... Enter" cr: waitkey()
  31.    else      
  32.        lines[x] = "Line " x " = " lines[x]
  33.        print lines[x] " ok " cr    
  34.    end if
  35. next x
  36.  
  37. print "Enter to end ..."
  38. waitkey()
  39.  

Another option is to use ParseUtil.inc. You will need a parser sooner or later :)

  if InstrWord(1," _Sue _Tom ",lines[ x]) then

Code: OxygenBasic
  1. includepath "$\inc\"
  2. include "console.inc"
  3. include "ParseUtil.inc"
  4. include "MathMisc.inc"
  5.  
  6. indexbase 1
  7.  
  8. dim as string Lines[100]={32}
  9.  
  10. int lastline=countof lines
  11. int length
  12.  
  13. 'fill array randomly
  14. for x=1 to lastline
  15.     length=abs(rnd()*5) +5
  16.     lines[x]=""
  17.     for l=1 to length
  18.        lines[x]&=chr(abs(rnd()*48)+60)
  19.     next l
  20.     print lines[x] cr
  21. next x
  22.  
  23. print"Enter to continue ..." cr cr: waitkey()
  24.  
  25. lines[10]="_Sue"
  26. lines[90]="_Tom"
  27.  
  28. for x=1 to LastLine
  29.    if InstrWord(1," _Sue _Tom ",lines[x]) then
  30.        print lines[x] " found in line " x " ... Enter" cr: waitkey()
  31.    else      
  32.        lines[x] = "Line " x " = " lines[x]
  33.        print lines[x] " ok " cr    
  34.    end if
  35. next x
  36.  
  37. print "Enter to end ..."
  38. waitkey()
  39.  
« Last Edit: April 09, 2015, 07:42:47 AM by Charles Pegge »

Arnold

  • Guest
Re: Correct way to compare strings?
« Reply #3 on: April 09, 2015, 11:45:30 AM »
Hi Charles,

thank you for the alternative solutions. They all work fine and are very fast.

Roland

Aurel

  • Guest
Re: Correct way to compare strings?
« Reply #4 on: April 09, 2015, 01:13:29 PM »
or maybe you can try this api function:
Code: [Select]
Declare Function lstrcmpi Lib "kernel32.dll" Alias "lstrcmpiA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long

Aurel

  • Guest
Re: Correct way to compare strings?
« Reply #5 on: April 09, 2015, 01:28:30 PM »
and here is a small test:
Code: [Select]
'string compare API
! lstrcmpi Lib "kernel32.dll" Alias "lstrcmpiA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
string a,b
INT res
a="OXYGEN" : b="oxygen"
res=lstrcmpi(a,b)
print str(res)+" OK"
'-----------------------------
a="OXYGEN" : b="Oxygen"
res=lstrcmpi(a,b)
print str(res)+" OK"
'-----------------------------
a="OXYGEN" : b="PXYGEN"
res=lstrcmpi(a,b)
print str(res)+ " NEGATIVE-first string is less than second"

Charles Pegge

  • Guest
Re: Correct way to compare strings?
« Reply #6 on: April 09, 2015, 11:05:47 PM »
Fixed :)

Oxygen DLL Update (200k)
http://www.oxygenbasic.org/o2zips/Oxygen.zip

Code: OxygenBasic
  1.  
  2. 'includepath "$\inc\"
  3. 'include "glo2\glMaths.inc"
  4.  
  5. ' Compare strings in array
  6.  
  7. includepath "$\inc\"
  8. include "console.inc"
  9. include "MathMisc.inc"
  10.  
  11. indexbase 1
  12.  
  13. dim as string Lines[100]
  14.  
  15. int lastline=countof lines
  16. int length
  17.  
  18. 'fill array randomly
  19. for x=1 to lastline
  20.     length=abs(rnd()*5) +5
  21.     lines[x]=""
  22.     for l=1 to length
  23.        lines[x]&=chr(abs(rnd()*48)+60)
  24.     next l
  25.     print lines[x] cr
  26. next x
  27.  
  28. print"Enter to continue ..." cr cr: waitkey()
  29.  
  30. lines[10]="_Sue"
  31. lines[90]="_Tom"
  32.  
  33. for x=1 to LastLine
  34.    if lines[x]="_Tom" or lines[x]="_Sue" then
  35.        print lines[x] " found in line " x " ... Enter" cr: waitkey()
  36.    else      
  37.        lines[x] = "Line " x " = " lines[x]
  38.        print lines[x] " ok " cr    
  39.    end if
  40. next x
  41.  
  42. print "Enter to end ..."
  43. waitkey()
  44.