0
votes

When completing a certain method that calculates a value, and sets a TText.text to that value, I get the following error thrown:

'String index out of range. (-1) Must be >=0 and <=0'

I made sure my calculation was safe and handled possible exceptions before and after they may occur. It is really just a simple addition calculation....

A quick google search led me to: Firemonkey: Setting TLabel Text causes String Index out of Range Exception

1) I am not using carriage returns though, nor any line breaks. This is my code for setting the ttext value -

TotalCost.text:='$'+FormatFloat('0.00',total);

2) It is not a TLabel, but a TText component.

3) This does not throw any errors on any Android Device, the simulator or my 4th gen iPad running iOS 9.0.2, but DOES throw errors on the newer iPhones also running iOS 9.

Any ideas on a workaround or bug fix? Hard to debug which line exactly throws the error since I do not have direct access to a newer iPhone nor does the devices I have or simulator throw an exception when debugging.

Thanks

2
why the close vote? Because my question is too 'lengthy, or not concise'? Well isn't that contradictory to how often I see Stack Overflow normals blast new members for the questions not providing enough details?ThisGuy
You need to do some debugging. Quite hard to see how we can help. Narrow the problem down, isolate it.David Heffernan
The error message is odd, sounds as though whatever is producing it would only be satisfied with a String index of zero. Hey ho ...MartynA
This particular exception comes from the functions in the System.Character class when passed string indexes as parameters. Up to, and including, XE8, those functions expect 1-based indexes on all platforms. But the error message says the index must be >=0 (it says >=1 in XE8), so EMB must have updated the functions in Seattle to account for 0-based strings on mobile platforms, and that change is apparently broken in some cases. I don't have Seattle installed to verify this, though.Remy Lebeau
Can you provide a short, self contained example that illustrates the problem?Shannon Matthews

2 Answers

1
votes

The index is raised in System.Character by a call to CheckZeroStringRange. The relevant definitions:

resourcestring
  sArgumentOutOfRange_StringIndex = 
    'String index out of range (%d).  Must be >= %d and <= %d';

class procedure TCharHelper.RaiseCheckStringRangeException(Index, LowIndex, 
  MaxIndex: Integer);
begin
  raise EArgumentOutOfRangeException.CreateResFmt(@sArgumentOutOfRange_StringIndex, 
    [Index, LowIndex, MaxIndex]) at ReturnAddress;
end;

procedure CheckZeroStringRange(const S: string; Index: Integer); inline;
var
  MaxIndex: Integer;
begin
  MaxIndex := High(S);
  if (Index > MaxIndex) or (Index < 0) then
    Char.RaiseCheckStringRangeException(index, 0, MaxIndex);
end;

Now your error indicates that your code is trying to access a zero-based string of length 1, with index -1. That is what your error message tells you.

There are 20 calls to CheckZeroStringRange in System.Character. They are all very similar and look like this:

class function TCharHelper.IsDigit(const S: string; Index: Integer): Boolean;
var
  C: UCS4Char;
begin
  CheckZeroStringRange(S, Index);
  C := UCS4Char(S[Index]);
  if IsLatin1(C) then
    Result := C in [$0030..$0039] // '0' / '9'
  else
    Result := InternalGetUnicodeCategory(ConvertToUtf32(S, Index)) = 
      TUnicodeCategory.ucDecimalNumber;
end;

So, something in your program is making a call that looks like this:

if TCharHelper.IsDigit(str, -1) then // BOOM!

Of course, it won't be exactly like this, but this is as much as we can discern.

Your next step is to do some debugging. If you cannot debug directly on the device, you need to add some trace logging to your program to identify the sequence of calls that lead to the error. The defect could be in your code, or it could be in the Delphi library code, or it could be in some third party code that you use. Again, we cannot say.

I don't think any more information can be provided given the facts you present in the question.

0
votes

I had same error, when I'm using #10 as line break (GlobalUseGPUCanvas := true). I changed it to #13#10 and it works.