当我的字符串包含#0字符时,为什么ShowMessage会给出意外的输出?

583*_*746 -3 delphi string delphi-10-seattle

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

showmessage(menuMain.player[2] + ' ready!');
Run Code Online (Sandbox Code Playgroud)

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

播放机

但是如果我以这种方式放置代码(例如menuMain.player [2] = Player):

showmessage('Test: ' + menuMain.player[2]);
Run Code Online (Sandbox Code Playgroud)

它将生成此消息:

测试:玩家

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

'玩家'#0#0#0#0#0#0#0'0'准备就绪!'

我老实说相信这是一个编译器故障,因为我在另一个代码块中有完全相同的行,并且它完美无缺.

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

Ken*_*ite 6

缓冲区字符串的确切值(buffer = menuMain.player [2] +'ready!'):'播放器'#0#0#0#0#0#0#0'0'准备就绪!'

问题是嵌入的空字符(the #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;
Run Code Online (Sandbox Code Playgroud)

当然,剩下的问题是你是如何在一开始就得到那些嵌入式空值的?由于你没有发布填充的代码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;
Run Code Online (Sandbox Code Playgroud)

所以你的问题的答案

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

这是一个小故障,但故障是代码中的某个地方.这不是Delphi或其字符串的故障.