WCHAR_Tは、Visual StudioおよびStore UTF-16で2バイトです。 Unicode-Awareアプリケーションは、U+FFFFの上の文字とどのように機能しますか?

StackOverflow https://stackoverflow.com/questions/4376812

質問

当社は、アプリケーションをUnicode-Awareにすることを計画しており、遭遇する問題を分析しています。

特に、私たちのアプリケーションは、たとえば、文字列の長さに大きく依存しており、使用したい 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

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

次に、UTF-8:F0 90 92 A2で、キャラクター𐒢(U+104A2)を入力として取得しましょう。

今回は、3つのwchar_tとstd :: wstring :: size returns 2にスペースを割り当てます。 私はそれを考えていても キャラクターは1人しかいません.

これには問題があります。 UTF-8でデータを受け取ると仮定しましょう。同等のバイトをカウントしないだけで、ユニコード文字をカウントできます 10xxxxxx. 。そのデータを配列にインポートしたい wchar_t それを扱うために。文字の数と1つを割り当てるだけの場合、安全かもしれません...一部の人がu+ffffの上のキャラクターを使用するまで。そして、バッファーが短すぎてアプリケーションがクラッシュします。

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

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

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

役に立ちましたか?

解決

あなたはstd :: wstring :: sizeを受け入れる必要があります いいえ 文字の数を与えます。代わりに、コードユニットの数が得られます。 16ビットのコードユニットがある場合、文字列にそれらの数を決定します。 Unicode文字の数を計算するには、文字列にループする必要があります。あなたがそれを受け入れたら、それはもう迷惑になりません。

UTF-8で文字をカウントすることに関して:しないでください。代わりに、投稿したコードは問題ありません。MultibytetowideCharを呼び出すと、必要なコードユニットの数がわかります。BMP文字または補足機用であっても、適切な番号を割り当てます。独自のカウントルーチンを絶対に書きたい場合は、そのうちの2つを持っています。1つは文字をカウントするもの、もう1つは16ビットコードユニットをカウントするものです。リードバイトが11110xxxの場合、2つのコード単位をカウントする必要があります。

他のヒント

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

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top