为什么这个字符串不包含正确的字符?

时间:2014-10-16 23:28:25

标签: string delphi serial-port delphi-xe3

用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;并有一些很好的选择。

谢谢!

1 个答案:

答案 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语言环境决定。

字符串用于文本。对于二进制使用字节数组。