10

C++ で JSON パーサーを作成していますが、JSON 文字列を解析するときに問題に直面しています。

JSON 仕様では、JSON 文字列に次の形式の Unicode 文字を含めることができると規定されています。

"here comes a unicode character: \u05d9 !"

私の JSON パーサーはstd::string、通常、JSON 文字列の 1 文字がstd::string. ただし、これらのユニコード文字については、どうすればよいか本当にわかりません。

生のバイト値を私のstd::stringように入れるべきですか:

std::string mystr;
mystr.push_back('\0x05');
mystr.push_back('\0xd9');

または、次のようなライブラリで 2 つの文字を解釈し、iconv代わりに UTF-8 でエンコードされた結果を文字列に格納する必要がありますか?

std::wstringすべての文字を格納するために a を使用する必要がありますか? wchar_tでは、長さが 4 バイトの*NIX OS ではどうでしょうか。

ソリューションに何か問題があると感じていますが、何がわからないのですか。その状況で私は何をすべきですか?

4

2 に答える 2

15

H2CO3 のコメントPhilipp のコメントのおかげで、掘り下げた後、これがどのように機能するかを最終的に理解できました。

RFC4627のセクションを読む3. Encoding:

  1. エンコーディング

    JSON テキストは Unicode でエンコードする必要があります。デフォルトのエンコーディングは
    UTF-8 です。

    JSON テキストの最初の 2 文字は常に ASCII 文字 [RFC0020] であるため、オクテット
    ストリームが UTF-8、UTF-16 (BE または LE)、または UTF-32 (BE または LE) であるかどうかを判別できます。
    最初の 4 オクテットのヌルのパターンを調べます。

       00 00 00 xx  UTF-32BE
       00 xx 00 xx  UTF-16BE
       xx 00 00 00  UTF-32LE
       xx 00 xx 00  UTF-16LE
       xx xx xx xx  UTF-8
    

したがって、JSON オクテット ストリームは、UTF-8、UTF-16、または UTF-32 (最後の 2 つは BE または LE バリアントの両方) でエンコードできるようです。

それが明確になったら、JSON 文字列でこれらの値Section 2.5. Stringsを処理する方法を説明します。\uXXXX

任意の文字をエスケープできます。文字が基本
多言語面 (U+0000 から U+FFFF まで) にある場合、6 文字のシーケンスとして表すことが でき
ます 。文字のコードポイント。16 進文字の A から F は、大文字または小文字にすることができます。そのため、たとえば、逆スリダス文字を 1 つだけ含む文字列は、 "\u005C" と表すことができます。




Basic Multilingual Planeにない文字については、より完全な説明があります。

Basic Multilingual Plane にない拡張文字をエスケープするために、文字は
、UTF-16 サロゲート ペアをエンコードする 12 文字のシーケンスとして表されます。したがって、たとえば
ト音記号文字 (U+1D11E) のみを含む文字列は、
「\uD834\uDD1E」と表すことができます。

お役に立てれば。

于 2012-10-28T10:00:57.267 に答える
2

私があなたなら、std::string を使用して UTF-8 と UTF-8 のみを保存します。着信 JSON テキストに \uXXXX シーケンスが含まれていない場合、 std::string をバイト単位で変換せずにそのまま使用できます。

\uXXXX を解析するときは、単純にデコードして UTF-8 に変換するだけで、その場所で真の UTF-8 文字であるかのように効果的に処理できます。これは、ほとんどの JSON パーサーがとにかく行っていることです (確かに libjson)。

確かに、このアプローチでは、\uXXXX で JSON を読み取り、ライブラリを使用してすぐにそれをダンプすると、\uXXXX シーケンスが失われ、それらが真の UTF-8 表現に置き換えられる可能性がありますが、本当に気にする人はいますか? 最終的に、正味の結果はまったく同じです。

于 2012-10-28T08:43:01.137 に答える