Delphi 2009 RawByteString变幻莫测

时间:2009-01-31 05:12:35

标签: delphi unicode utf-8 delphi-2009 rawbytestring

假设出于某些不正当的原因,您希望显示UTF8String的原始字节内容。

var
  utf8Str : UTF8String;
begin    
  utf8Str := '€ąćęłńóśźż';
end;

(1)这不行,它显示可读形式:

memo1.Lines.Add( RawByteString( utf8Str ));
// output: '€ąćęłńóśźż'

(2)然而,这确实“有用” - 请注意连接:

memo1.Lines.Add( 'x' + RawByteString( utf8Str ));
// output: 'x€ąćęłńóśźż'

我理解(1),尽管编译器强制转换为UnicodeString似乎阻止了按原样显示RawByteString var。但是,为什么行为会在(2)中发生变化?

(3)陌生人仍然 - 让我们扭转连接:

memo1.Lines.Add( RawByteString( utf8Str ) + 'x' ); 
// output: '€ąćęłńóśźżx'

我一直在阅读Delphi中新奇的字符串类型,并认为我理解它们是如何工作的,但这是一个难题。

2 个答案:

答案 0 :(得分:9)

RawByteString仅用于最小化函数所需的重载次数,这些函数适用于具有不同代码页亲和度的各种AnsiString个。{/ p>

通常,不要声明类型为RawByteString的变量。不要将值类型转换为该类型。不要对该类型的变量进行连接。关于你唯一能做的事情是:

  • 声明此类型的参数(原始意图)
  • 对此类参数建立索引
  • 在这样的参数中搜索
  • 使用StringCodePage函数检查字符串实际代码页的智能操作。

例如,您会注意到StringCodePage函数本身使用RawByteString作为其参数类型。这样,它可以与任何AnsiString一起使用,而不是在将其作为参数传递之前进行代码页翻译。

对于你的情况,连接之类的东西很大程度上是未定义的。 RTM和Update 2之间的行为发生了变化,但是当RTL字符串连接函数接收到具有不同代码页的多个字符串时,没有简单的方法可以找出应该用于最终字符串的代码页。这就是为什么你不应该像在这里那样连接它们的原因之一。

答案 1 :(得分:1)

您无法“按原样”将字符串添加到TMemo。你总是需要转换为Unicode,因为这是TMemo在Delphi 2009中所知道的。

如果您想假装您的UTF8String使用代码页1252,请执行以下操作:

var
  utf8Str : UTF8String;
  Raw: RawByteString;
begin
  utf8Str := '€ąćęłńóśźż';
  Raw := utf8Str;
  SetCodePage(Raw, 1252, False);
  Memo.Lines.Add(Raw);
end;

有关详细信息,请参阅我的文章Using RawByteString Effectively