2009-01-31 33 views
5

假设出于某种不正当的原因想要显示UTF8String的原始字节内容。Delphi 2009 RawByteString变幻莫测

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' 

我已经在德尔福新奇的字符串类型读了,我想我明白他们是如何工作的,但是这是一个谜。

回答

9

RawByteString只存在于最大限度地减少功能所需的重载次数,这些重载功能可用于具有不同代码页亲和力的各种风格的AnsiString

通常,不要声明类型为RawByteString的变量。不要为此类型指定值。不要对该类型的变量进行连接。关于你唯一可以做的事情是:

  • 声明这种类型的参数(原意)
  • 索引这样的参数
  • 在这样的参数搜索
  • ,办理入住手续的智能操作字符串的实际代码页,使用StringCodePage函数。

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

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

+0

Thans,Barry,这很有道理。级联只是一个“如果我按下这个按钮”实验,没有任何实际价值。 奇怪的是,虽然看到德尔福引入了这样一个未定义的行为 - 从来没有很多这样的。 – 2009-01-31 19:22:23

1

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

如果你想假装你的UTF8字符串使用代码页1252,这样做:

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

对于更多细节,请参阅我的文章Using RawByteString Effectively

+0

UTF-8是一个8位编码。它要求代码单元$ 00- $ FF按原样处理。但是,当转换为UTF-16时,代码页1252将代码单元$ 80- $ 9F映射到不同的值。您应该使用代码页28591(ISO-8859-1)。 – 2016-04-07 02:49:22