当我的字符串包含#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'准备好了!'
我真的相信这是一个编译器故障,因为我已经在另一个代码块确切同一直线上,并且它完美的作品。
现在对我来说困难的部分是,我是愚蠢的,或者这确实是一个小故障?
缓冲区字符串的确切值(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];)。在写符号时我没有检查输入[i] #0。我将为问题主体添加解决方案。感谢您的帮助! :) –
你对'menuMain'的声明是什么? – MartynA
请提供一个我们可以用来重现此问题的[mcve]。 –
@MartynA menuMain是该项目的主要形式,player是数组[1..2]的字符串。 –