2014-10-16 4 views
0

Delphi XE3로 작성된 필자의 소프트웨어는 때때로 바이너리 데이터를 전송하는 계측기와 통신하고 있습니다. 이 데이터는 결코 유니 코드가 아니기 때문에 AnsiString을 사용해야한다고 예상 했었습니다. 다음 코드가 예상대로 작동하지 않는다고 나는 믿을 수 없었다. 나는 당연히 ... 나는 그것을 노출하고있어 문자가 불법으로 간주되는 것을왜이 문자열에 올바른 문자가 포함되어 있지 않습니까?

var 
    s:AnsiString; 
begin 
    s:='test' + chr(128); 

    // had expected that since the string was set above to end in #128, 
    // it should end in #128...it does not. 
    if ord(s[5])<>128 then 
    ShowMessage('String ending is not as expected!'); 
end; 

을 상정하고있어, 나는 이러한 목표를 달성하기 위해 포인터를 사용할 수 있지만, 나는 아마 문자열의 다른 종류를 사용한다 생각 . 물론 바이트 배열을 사용할 수도 있지만 문자열이 더 편리 할 것입니다.

정말 "왜"인지 알고 좋은 대안을 원합니다.

감사합니다.

+0

"예상했던대로 작동하지 않습니다"라는 의미를 설명하기 위해 질문을 편집 할 수 있습니까? 실제 및 예상 출력 또는 정확한 오류 메시지는 무엇입니까? – IMSoP

+0

내 질문에 개선됨 –

+2

어떤 버전의 Delphi를 사용하고 있습니까? 델파이 2009+에서'AnsiString'은 코드 페이지를 인식하고, 문자 128-255는 코드 페이지와 관련이 있으며,'Chr()'은 유니 코드를 구분합니다. 유니 코드를 신경 쓰지 않고 128을 그대로 취급하고 싶다면'Chr (128)'대신'AnsiChar (128)'을 사용하십시오. –

답변

3

관찰 된 동작은 Chr(128)U+0080을 나타내는 UTF-16 WideChar이라는 사실에서 유래했습니다.

ANSI 로캘로 변환 할 때 서수 128에 매핑되지 않습니다. U + 0080에 ANSI 로캘에 해당하는 것이 없으므로 ?에 매핑하여 번역에 실패했음을 나타냅니다.

실제로 컴파일러는 경고 메시지가 표시 될 수도 있습니다. 기본 컴파일러 옵션을 사용하여 컴파일하면 코드는 이러한 경고를 얻을 :

 
W1058 Implicit string cast with potential data loss from 'string' to 'AnsiString' 
W1062 Narrowing given wide string constant lost information 

가 개인적으로 오류로 그 경고를 모두 처리하도록 경고를 구성 사용할 수 있습니다.

근본적인 문제는 여기 계시 :

내 소프트웨어는 종종 이진 데이터를 보내는 장비와 통신한다.

바이트 지향 바이너리 데이터의 올바른 데이터 형식은 바이트 배열입니다. 델파이에서는 TBytes이 될 것입니다.

AnsiString은 코드 페이지 번역을 제공하므로 잘못 사용하는 것이 좋습니다. 서수 값을 지정할 수 있기를 원하며 텍스트 인코딩이 부분적으로 재생되는 것을 원하지 않을 수도 있습니다. 프로그램의 동작이 일반적인 ANSI 로켈에 의해 결정되기를 원하지 않습니다.

문자열은 텍스트입니다. 바이너리의 경우에는 바이트 배열을 사용하십시오.