2016-09-04 75 views
-3

今天我偶然發現了一些神祕的東西。這行代碼:當我的字符串包含#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]的字符串。 –

回答

6

緩衝區字符串的確切值(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。我將爲問題主體添加解決方案。感謝您的幫助! :) –

相關問題