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

问题描述:

今天我偶然发现了一些神秘的东西。这行代码:当我的字符串包含#0个字符时,为什么ShowMessage会给出意想不到的输出?

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

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

播放

但是,如果我把代码这种方式(对于例如menuMain.player [2] =播放器):

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

它将产生这样的信息:

测试:球员

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

'球员' #0#0#0#0#0# 0#0#0'准备好了!'

我真的相信这是一个编译器故障,因为我已经在另一个代码块确切同一直线上,并且它完美的作品。

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

+0

你对'menuMain'的声明是什么? – MartynA

+1

请提供一个我们可以用来重现此问题的[mcve]。 –

+0

@MartynA menuMain是该项目的主要形式,player是数组[1..2]的字符串。 –

缓冲区字符串的确切值(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或其字符串中的小故障。

+0

那你来回答!当我通过代码时,我提出了一个可能的解决方案,但我需要确认。我收到来自TCustomWinSocket的menuMain.player [2],但在这个组件函数SentText(我使用)使用AnsiString类型,是否有任何可能的方式,从AnsiString转换为常规字符串导致#0损坏?再次感谢:) –

+0

不,AnsiString为*常规字符串*不添加#0个字符。我不能告诉你使用TCustomWinSocket有什么问题,因为我看不到那些代码(这将是一个完全不同的问题,您应该在新问题中询问这个问题)。 –

+0

哦,我发现问题,这确实是我的愚蠢。我使用输入字符串来获取menuMain.player [2]逐符号(例如buf [1]:= input [16];)。在写符号时我没有检查输入[i] #0。我将为问题主体添加解决方案。感谢您的帮助! :) –