3

私たちは、アプリケーションをUnicode対応にすることを計画しており、発生する問題を分析しています。

wchar_t特に、私たちのアプリケーションは、たとえば文字列の長さに大きく依存するため、基本文字クラスとして使用したいと思います。

この問題は、UTF-16で16ビットの2単位で格納する必要のある文字、つまりU+10000を超える文字を処理するときに発生します。

簡単な例:

UTF-8文字列"蟂"(Unicode文字U + 87C2、UTF-8:E8 9F 82)があります

そこで、次のコードを設定します。

const unsigned char my_utf8_string[] = { 0xe8, 0x9f, 0x82, 0x00 };

// compute size of wchar_t buffer.
int nb_chars = ::MultiByteToWideChar(CP_UTF8,                                  // input is UTF8
                                     0,                                        // no flags
                                     reinterpret_cast<char *>(my_utf8_string), // input string (no worries about signedness)
                                     -1,                                       // input is zero-terminated
                                     NULL,                                     // no output this time
                                     0);                                       // need the necessary buffer size

// allocate
wchar_t *my_utf16_string = new wchar_t[nb_chars];

// convert
nb_chars = ::MultiByteToWideChar(CP_UTF8,
                                 0,
                                 reinterpret_cast<char *>(my_utf8_string),
                                 -1,
                                 my_widechar_string, // output buffer
                                 nb_chars);          // allocated size

さて、これは機能し、16ビットを2回割り当て、のバッファにwchar_tは{0x87c2、0x0000}が含まれています。それをaの中に保存しstd::wstringてサイズを計算すると、1になります。

ここで、UTF-8:F0 90 92 A2の入力として文字(U + 104A2)を使用します。

今回は、3つのwchar_tにスペースを割り当て、std :: wstring :: sizeは、文字が1つしかないことを考慮しても、 2を返します。

これには問題があります。UTF-8でデータを受信すると仮定します。に等しいバイトをカウントしないだけで、Unicode文字をカウントできます10xxxxxx。そのデータを配列にインポートして処理したいと思いwchar_tます。文字数に1を足した数を割り当てるだけなら、安全かもしれません...誰かがU+FFFFより上の文字を使用するまで。そして、バッファが短すぎて、アプリケーションがクラッシュします。

それで、同じ文字列で、異なる方法でエンコードされた場合、文字列内の文字をカウントする関数は異なる値を返しますか?

この種の煩わしさを回避するために、Unicode文字列で動作するアプリケーションはどのように設計されていますか?

返信ありがとうございます。

4

2 に答える 2

7

std :: wstring::sizeは文字数を示さないことを受け入れる必要があります。代わりに、コードユニットの数がわかります。16ビットコードユニットがある場合は、文字列に含まれるコードユニットの数が決まります。Unicode文字の数を計算するには、文字列をループする必要があります。あなたがそれを受け入れれば、それはもう迷惑ではありません。

UTF-8で文字を数えることに関しては:しないでください。代わりに、投稿したコードは問題ありません。MultiByteToWideCharを1回呼び出すと、必要なコードユニットの数がわかります。次に、BMP文字用か補助プレーン用かを問わず、正しい番号を割り当てます。どうしても独自のカウントルーチンを作成したい場合は、2つ用意してください。1つは文字をカウントし、もう1つは16ビットコード単位をカウントします。リードバイトが11110xxxの場合、2つのコードユニットをカウントする必要があります。

于 2010-12-07T13:05:43.297 に答える
3

Unicodeの公式Webサイトから次のFAQを読むことをお勧めします:http://www.unicode.org/faq//utf_bom.html

基本的に、コードユニット、コードポイント、および文字を区別することが重要です。

于 2010-12-07T16:46:42.660 に答える