【问题标题】:Why does ShowMessage give unexpected output when my string contains #0 characters?当我的字符串包含 #0 个字符时,为什么 ShowMessage 会给出意外的输出?
【发布时间】:2016-09-04 21:24:40
【问题描述】:

今天我偶然发现了一些神秘的东西。这行代码:

showmessage(menuMain.player[2] + ' ready!');

生成此消息(例如 menuMain.player[2] = Player):

播放器

但是如果我这样写代码(例如 menuMain.player[2] = Player):

showmessage('Test: ' + menuMain.player[2]);

它将生成此消息:

测试:播放器

根据调试器,字符串(buffer := menuMain.player[2] + ' ready!')的确切值是这样的:

'玩家'#0#0#0#0#0#0#0#0'准备好了!'

我确实相信这是一个编译器故障,因为我在另一个代码块中有 exact 相同的行,并且它完美地工作。

现在对我来说最困难的部分是我笨,还是这确实是一个小故障?

【问题讨论】:

  • 你对menuMain的声明是什么?
  • 请提供minimal reproducible example,我们可以使用它来重现此问题。
  • @MartynA menuMain是项目的主要形式,player是字符串的array[1..2]。
  • @RobKennedy 缓冲区字符串的确切值 (buffer = menuMain.player[2] + 'ready!'): 'Player'#0#0#0#0#0#0#0# 0'准备好了!'
  • 很好的信息。有人可以给出明确的答案就足够了。此外,您还学会了检查调试器。

标签: string delphi delphi-10-seattle


【解决方案1】:

缓冲区字符串的确切值 (buffer = menuMain.player[2] + 'ready!'): 'Player'#0#0#0#0#0#0#0#0' ready!'

问题在于嵌入的空字符(#0)。这些字符充当字符串终止符,这意味着对于大多数 WinAPI 函数(包括那些输出或绘制文本的函数),该字符串在该点停止处理。当找到第一个#0 时,该字符串被认为已经结束。

您可以自己轻松地进行测试,代码如下:

var
  TestStr: string;
begin
  TestStr := 'This is a test';
  ShowMessage(TestStr);          // Outputs This is a test
  TestStr[5] := #0;
  ShowMessage(TestStr);          // Outputs This
end;

当然,剩下的问题是,您最初是如何得到这些嵌入式空值的?由于您尚未发布填充menuMain.player 的代码,因此无法说,但这就是您需要检查的区域,因为 Delphi 中的字符串数组元素本身不包含空值。您也可以自己检查:

var
  TestArr: array[1..2] of string;
begin
  TestArr[1] := 'Player one';
  TestArr[2] := 'Player two';
  ShowMessage(TestArr[1] + ' defeated ' + TestArr[2]);
end;

所以你的问题的答案

现在对我来说最困难的部分是我笨,还是这确实是一个小故障?

这是一个故障,但故障在您的代码中。这不是 Delphi 或其字符串的故障。

【讨论】:

  • 您的答案!当我浏览代码时,我想出了一个可能的解决方案,但我需要确认。我从 TCustomWinSocket 收到 menuMain.player[2],但是在这个组件函数 SentText(我使用的)中使用 AnsiString 类型,是否有任何可能的方式从 AnsiString 转换为常规字符串导致 #0 损坏?再次感谢:)
  • 不,AnsiString 到 常规字符串 也不添加 #0 字符。我无法告诉您使用 TCustomWinSocket 有什么问题,因为我看不到该代码(这将是一个完全不同的问题,您应该在新问题中询问)。
  • 哦,我发现了问题,这确实是我的愚蠢。我使用输入字符串逐个符号地获取 menuMain.player[2](例如 buf[1] := input[16];)。我没有检查 input[i] #0 是否写入符号。我将在问题主体中添加解决方案。感谢您的帮助! :)
  • 不,不要将该解决方案添加到问题正文中,因为它不是此问题的一部分。正如我之前所说,这是一个不同的问题。我已经回答了你在这里提出的问题。
猜你喜欢
  • 2014-04-09
  • 1970-01-01
  • 2010-12-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多