0

This code is working in a Firemonkey Windows app, but doesn't work in Android app, i get Goodbye instead of Welcome, what is wrong?

Edit8 Text : 162496 //Computer unique code

Edit9 Text : 1564224593 //serial #

  procedure TForm2.Button5Click(Sender: TObject);
  var
   f2,f1:textfile;
   i,j:byte;
   s1,s2,s3,c:string;
   F: TextFile;
  begin
    j:=0;
    s2 := Edit8.Text;

    for i:=1 to  Length(s2) do
    if (s2[i]>='0') and (s2[i]<='9') then
    s3:=s3+s2[i];

    for i:=1 to  Length(s3)-1 do
    if (edit9.Text[i*2-1]<>s3[i]) or (abs(strtoint(s3[i+1])-strtoint(s3[i]))<> strtoint(edit9.Text[i*2])) then 
    inc(j);

    if j=0 then
      ShowMessage('Welcome')
    else
       ShowMessage('Goodbye');
  end;
Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
unknown
  • 65
  • 1
  • 2
  • 9

2 Answers2

4

Delphi mobile compilers use zero-based strings.

You have three choices:

  1. As @Günter_the_Beautiful points out, your best choice is to rewrite your code to use string helpers (which are always 0-based)
  2. Rewrite your code to use 0-based indexing: for I := 0 to ...
  3. If you need a quick fix, turn it off locally for your code snippet using the {$ZEROBASEDSTRINGS OFF} directive (and revert it back with {$ZEROBASEDSTRINGS ON} again).

For options 2. and 3., if you need your code to be cross-platform, consider using appropriate platform conditional defines. This is what makes option 1. compelling: no need to clutter your code with conditional defines.

Ondrej Kelle
  • 36,941
  • 2
  • 65
  • 128
  • 1
    I'd strongly advise **against** cluttering up your code with compiler directives just to keep an old weird habit of starting at index `1` instead of `0` like anywhere else. Since XE3 or something, there are String helpers that let you access the `Char` of a string with zero access with no need to worry about the platform it's running on: `if myString.Chars[0] = 'X' then ...`). See http://docwiki.embarcadero.com/Libraries/en/System.SysUtils.TStringHelper.Chars – Günther the Beautiful Dec 07 '16 at 09:17
  • well, i changed it to `I := 0` in both for loops, still same problem, rewrite full code? update your answer, Thanks @Ondrej Kelle – unknown Dec 07 '16 at 09:20
  • @unknown `... to Length(s2) - 1` ? `...to Length(s3) - 2` ? I mean... you can always, you know, try to use the debugger. And turn on range checking. Your indices have compound arithmetic in them. You have to sort it out for zero-based. Consider `[i*2-1]`. That's obviously going to go wrong right away. – J... Dec 07 '16 at 09:32
  • @unknown I suggest that you try a bit harder. This answer tells you what is wrong with your code. Now it's over to you to do some work. Don't be helpless. – David Heffernan Dec 07 '16 at 09:55
  • @unknown You don't need to compile an enormous project to debug this. Make a test application that you can compile in seconds. See : [mcve] – J... Dec 07 '16 at 17:43
  • @unknown It should not take 15 minutes to compile an empty project. Your HDD is probably ready to die... or something else is wrong. – J... Dec 07 '16 at 18:06
-1

I am using these two helper routines:

FUNCTION GetChar(CONST S : STRING ; OneBasedIndex : LongWord) : CHAR;
  BEGIN
    {$IF CompilerVersion>=24 }
      Result:=S[SUCC(OneBasedIndex-LOW(S))]
    {$ELSE }
      Result:=S[OneBasedIndex]
    {$IFEND }
  END;

PROCEDURE SetChar(VAR S : STRING ; OneBasedIndex : LongWord ; NewChar : CHAR);
  BEGIN
    {$IF CompilerVersion>=24 }
      S[SUCC(OneBasedIndex-LOW(S))]:=NewChar
    {$ELSE }
      S[OneBasedIndex]:=NewChar
    {$IFEND }
  END;

This way, you can continue working with strings as 1-based (which is the logical choice :-)) as long as you always access the strings as characters using these two functions.

HeartWare
  • 7,464
  • 2
  • 26
  • 30