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変数をそのまま表示できなくなるようです。しかし、なぜ(2)で動作が変わるのでしょうか。

(3)見知らぬ人はまだ-連結を逆にしましょう:

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

私はDelphiの新しい文字列タイプを読んでいて、それらがどのように機能するかを理解していると思いましたが、これはパズルです。

4

2 に答える 2

9

RawByteStringAnsiString異なるコードページ アフィニティを持つさまざまな種類の s で動作する関数に必要なオーバーロードの数を最小限に抑えるためにのみ存在します。

一般に、 type の変数は宣言しないでくださいRawByteString。その型に値を型キャストしないでください。その型の変数を連結しないでください。あなたができる唯一のことは次のとおりです。

  • この型のパラメーターを宣言する (元の意図)
  • そのようなパラメーターのインデックス作成
  • そのようなパラメータで検索する
  • StringCodePage関数を使用して、文字列の実際のコード ページをチェックするインテリジェントな操作。

たとえば、StringCodePage関数自体がRawByteString引数の型として を使用していることに気付くでしょう。このようにしAnsiStringて、引数として渡す前にコードページの変換を行うのではなく、任意の で機能します。

あなたの場合、連結のようなものはほとんど定義されていません。RTM と Update 2 の間で動作が変更されましたが、RTL 文字列連結関数が異なるコード ページを持つ複数の文字列を受け取った場合、最終的な文字列にどのコード ページを使用する必要があるかを判断する簡単な方法がありません。これが、ここで行っているようにそれらを連結してはならない理由の 1 つにすぎません。

于 2009-01-31T16:56:45.707 に答える
1

文字列を TMemo に「そのまま」追加することはできません。Delphi 2009 で TMemo が知っているのはこれだけなので、Unicode への何らかの変換が常に必要です。

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 に答える