【问题标题】:String Index Error Delphi Seattle字符串索引错误 Delphi Seattle
【发布时间】:2015-10-21 19:34:17
【问题描述】:

当完成某个计算值并将 TText.text 设置为该值的方法时,我收到以下错误:

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

我确保我的计算是安全的,并在异常发生前后处理了可能的异常。真的只是简单的加法计算....

快速的谷歌搜索让我发现: Firemonkey: Setting TLabel Text causes String Index out of Range Exception

1) 我没有使用回车,也没有使用任何换行符。这是我设置 ttext 值的代码 -

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

2) 不是TLabel,而是TText组件。

3) 这不会在任何运行 iOS 9.0.2 的 Android 设备、模拟器或我的第 4 代 iPad 上引发任何错误,但会在运行 iOS 9 的较新 iPhone 上引发错误。

关于解决方法或错误修复的任何想法?很难调试哪一行会引发错误,因为我无法直接访问较新的 iPhone,我拥有的设备或模拟器在调试时也不会引发异常。

谢谢

【问题讨论】:

  • 为什么是近距离投票?因为我的问题太“冗长或不简洁”?好吧,这与我看到 Stack Overflow 的法线经常因为没有提供足够详细信息的问题而抨击新成员的频率不矛盾吗?
  • 你需要做一些调试。很难看出我们能提供什么帮助。缩小问题范围,将其隔离。
  • 错误信息很奇怪,听起来好像无论什么产生它只会满足零字符串索引。嘿嘿...
  • 这个特殊的异常来自 System.Character 类中的函数,当将字符串索引作为参数传递时。在 XE8 之前(包括在内),这些函数在所有平台上都需要基于 1 的索引。但是错误消息说索引必须是&gt;=0(它在XE8中说&gt;=1),所以EMB必须更新西雅图的函数来解释移动平台上基于0的字符串,并且这种变化显然在某些方面被破坏了案例。不过,我没有安装西雅图来验证这一点。
  • 您能否提供一个说明问题的short, self contained example

标签: delphi delphi-10-seattle


【解决方案1】:

通过调用CheckZeroStringRangeSystem.Character 中引发索引。相关定义:

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;

现在您的错误表明您的代码正在尝试访问一个从零开始、长度为 1、索引为 -1 的字符串。这就是您的错误消息告诉您的内容。

System.Character 中有 20 次调用 CheckZeroStringRange。它们都非常相似,看起来像这样:

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;

因此,您的程序中的某些内容正在发出如下所示的调用:

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

当然,它不会完全像这样,但这是我们所能辨别的。

下一步是进行一些调试。如果您不能直接在设备上调试,则需要在程序中添加一些跟踪日志,以识别导致错误的调用序列。缺陷可能存在于您的代码中,也可能存在于 Delphi 库代码中,也可能存在于您使用的某些第三方代码中。同样,我们不能说。

鉴于您在问题中提出的事实,我认为无法提供更多信息。

【讨论】:

  • 不,这是 Tlabel 或字符串的问题(在 Delphi Berlin 上检查过)。设置 GlobalUseGPUCanvas := true;试试这个字符串:
  • TEXT1 = 'Google Docs 终于有了语法检查功能,可以识别混淆的词(如“affect”和“effect”),'#$ A'不正确的时态,不正确使用逗号和从句,等等。为了做到这一切,谷歌表示将“+”依赖机器翻译——与用于在多种语言之间进行翻译的“#$A”技术相同。除了将句子从法语翻译成德语之外,它听起来像“#$A”,尽管它会将你不完美的写作翻译成“+”语法正确的段落。 '#$A#$A'';
【解决方案2】:

当我使用 #10 作为换行符时,我遇到了同样的错误 (GlobalUseGPUCanvas := true)。我将其更改为 #13#10 并且可以正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-13
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    • 2018-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多