WCHAR_Tは、Visual StudioおよびStore UTF-16で2バイトです。 Unicode-Awareアプリケーションは、U+FFFFの上の文字とどのように機能しますか?
-
09-10-2019 - |
質問
当社は、アプリケーションを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
基本的に、コードユニット、コードポイント、文字を区別することが重要です。