Salvador
Salvador

Reputation: 16472

TStringHelper is not returning the correct results

I'm using the TStringHelper in a Win32 Application, but when I try to access a particular char or get a substring the values returned are not the same If I use the equivalent old string functions.

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

var
  i : Integer;
  s : string;
begin
  try
    i:=12345678;
    Writeln(i.ToString().Chars[1]);  // returns 2
    Writeln(i.ToString().Substring(1)); //returns 2345678

    s:=IntToStr(i);
    Writeln(s[1]); //returns 1
    Writeln(Copy(s,1,Length(s)));//returns 12345678
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

The question is Why the TStringHelper functions are not equivalent to the old string functions?

Upvotes: 4

Views: 1491

Answers (2)

Ken White
Ken White

Reputation: 125620

The TStringHelper functions are 0-based, not 1-based. From the linked docs for TStringHelper.Chars (emphasis mine):

Accesses individual characters in this zero-based string.

From the link for TStringHelper.SubString (again, emphasis mine):

Returns the substring starting at the position StartIndex and optionally ending at the position StartIndex + Length, if specified, from this 0-based string.

The code sample from the Chars link also shows the loop running from 0 to Length - 1, instead of the usual string loop that runs from 1 to Length(string) (code comment mine):

var
  I: Integer;
  MyString: String;

begin
  MyString := 'This is a string.';

  for I:= 0 to MyString.Length - 1 do  // Note start and end of loop condition
    Write(MyString.Chars[I]);
end.

Upvotes: 4

RRUZ
RRUZ

Reputation: 136391

This is because all the methods and properties of the System.SysUtils.TStringHelper are zero based index, this helper was compiler with the {$ZEROBASEDSTRINGS ON} directive. you can find more info in the System.SysUtils.TStringHelper documentation.

Upvotes: 11

Related Questions