用Delphi XE3编写,我的软件正在与偶尔发送二进制数据的仪器进行通信。我曾预料到我应该使用AnsiString,因为这个数据永远不会是Unicode。我无法相信以下代码没有像我预期的那样工作。我假设我曝光的角色被认为是非法的...
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;
当然,我可以用指针来完成这个,但我认为我应该使用不同类型的字符串。当然,我可以使用字节数组,但字符串会更方便。
真的,我想知道&#34;为什么&#34;并有一些很好的选择。
谢谢!
答案 0 :(得分: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
我个人会使用配置警告将这两个警告视为错误。
这里揭示了根本问题:
我的软件正在与偶尔发送二进制数据的仪器进行通信。
面向字节的二进制数据的正确数据类型是字节数组。在Delphi中,TBytes
。
使用AnsiString
是错误的,因为这会使您暴露于代码页翻译。您希望能够指定序数值,并且您明确地不希望文本编码发挥作用。您不希望程序的行为由当前的ANSI语言环境决定。
字符串用于文本。对于二进制使用字节数组。