5

假设出于某种不正当的原因,您想要显示 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 中新奇的字符串类型,并认为我理解它们是如何工作的,但这是一个谜。

4

2 回答 2

9

RawByteStringAnsiString仅存在以最小化使用具有不同代码页亲和力的各种风格的函数所需的重载数量。

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

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

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

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

于 2009-01-31T16:56:45.707 回答
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;

更多详细信息,请参阅我的文章有效地使用 RawByteString

于 2009-02-02T02:10:05.387 回答