2016-09-04 4 views
-3

오늘 나는 신비한 것을 발견했습니다. 이 코드 행 :문자열에 # 0 문자가 포함되어 있으면 ShowMessage에서 예기치 않은 결과가 나오는 이유는 무엇입니까?

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

(예를 들어 menuMain.player [2] = 플레이어)이 메시지를 생성합니다 :

플레이어

그러나 나는 경우 (이런 식으로 코드를 삽입하는 경우 exampleMain.player [2] = Player) :

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

이 메시지는 다음과 같이 표시됩니다.

테스트 :

'플레이어'# 0 # 0 # 0 # 0 # 0 # : 플레이어

디버거에 따르면, 문자열 (buffer := menuMain.player[2] + ' ready!')의 정확한 값은 이것이다 0 # 0 # 0 '준비!'

솔직히 내가 코드의 다른 블록에서 정확한 같은 라인을 가지고 있기 때문에 이것은, 컴파일러 결함이라고 생각합니까, 그것은 완벽하게 작동합니다.

나를 위해 힘든 부분은, 내가 바보가되고있는 것입니까, 아니면 실제로 이것은 결함입니까?

+0

'menuMain' 선언은 무엇입니까? – MartynA

+1

이 문제를 재현하는 데 사용할 수있는 [mcve]를 제공해주십시오. –

+0

@MartynA menuMain은 프로젝트의 주된 형식이며, 플레이어는 string의 배열 [1..2]입니다. –

답변

6

버퍼 문자열의 실제 값 (버퍼 menuMain.player = [2] + 준비 '!') '플레이어'# 1 # 1 # 1 # 1 # 1 # 1 # 1 # 0 '을 준비! '

문제는 내장 된 널 문자 (#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; 

나머지 질문 물론, 당신이 처음에 그 포함 된 null로 끝낼 않았다 어떻게? menuMain.player으로 채워지는 코드를 게시하지 않았으므로 말할 필요도 없습니다. 델파이의 문자열 배열 요소는 null을 자체적으로 포함하지 않기 때문에 검사해야하는 부분입니다.

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

그래서 대답 질문 이제

나를 위해 힘든 부분에, 내가 바보 인, 또는이 참으로 결함 때문이다 : 당신은 또한 자신 있음을 확인할 수 있습니까?

글리치가 있지만 코드의 어딘가에 있습니다. 델파이 나 그 문자열의 결함이 아닙니다.

+0

대답 해 줘! 코드를 살펴볼 때 가능한 해결책이 떠오르지 만 확인이 필요합니다. TCustomWinSocket에서 menuMain.player [2]를 받았지만,이 컴포넌트 함수 SentText (내가 사용하는)에서 AnsiString 유형을 사용합니다. AnsiString에서 일반 문자열로의 변환이 # 0 손상을 일으키는 가능한 방법이 있습니까? 다시 한 번 감사드립니다 :) –

+0

아니요, AnsiString to * regular string *은 # 0 문자를 추가하지 않습니다. TCustomWinSocket을 사용하면 무엇이 잘못되었는지 말할 수 없습니다. 코드를 볼 수 없기 때문에 (그리고 새로운 질문에서 물어야 할 완전히 다른 문제 일 것입니다). –

+0

오, 나는 문제를 발견했다. 그리고 그것은 정말로 나의 어리 석음이었다. menuMain.player [2] 심볼을 얻기 위해 입력 문자열을 사용했습니다 (예제 buf [1] : = input [16];). 나는 symbol 작성에 input [i] <> # 0이 있는지 확인하지 않았다. 질문 본문에 해결책을 추가하겠습니다. 도와 줘서 고마워! :) –