2013-03-18 4 views
9

私はC++ 11の新しいUnicode機能を探求していましたが、other C++11 encoding questionsが非常に役に立ちましたが、cppreferenceから次のコードスニペットに関する質問があります。コードはUTF-8エンコーディングで保存されたテキストファイルを書き込み、すぐに読み取ります。C++でのUTF-8の読み書き/印刷11

// Write 
std::ofstream("text.txt") << u8"z\u6c34\U0001d10b"; 

// Read 
std::wifstream file1("text.txt"); 
file1.imbue(std::locale("en_US.UTF8")); 
std::cout << "Normal read from file (using default UTF-8/UTF-32 codecvt)\n"; 
for(wchar_t c; file1 >> c;) // ? 
    std::cout << std::hex << std::showbase << c << '\n'; 

私の質問は非常に単純に、なぜwchar_tforループで必要とされていますか? u8文字列リテラルは、単純なchar *を使用して宣言することができ、UTF-8エンコーディングのビットレイアウトは、システムに文字の幅を伝える必要があります。 UTF-8からUTF-32(したがってwchar_t)への自動変換があるようですが、この場合はどうして変換が必要ですか?

+0

多くのことに依存します。特筆すべきは、正しいUTF8の動作は、コンソールアプリケーションでWindowsを使用することは不可能ではないにしても非常に困難です(非標準API呼び出しIIRCが少なくとも必要です) – sehe

+1

'wcharstream'が使用され、' wifstream'が実行されるその "何らかの自動変換"と言います。私の指摘は、(ある特定のプラットフォームで実装された)自動変換と、 'codecvt_utf8_utf16'によって提供される明示的で移植性のある、ロケールに依存しないUnicode変換との違いを示すことでした。 – Cubbi

答えて

5

あなたがwifstreamを使用してファイルを読んでいるので、あなたがwchar_tを使用します。 ifstreamを使用して読んでいた場合は、charを使用し、char16_tchar32_tの場合も同様です。 (例がないとして)wchar_tは32ビットであり、ネイティブ文字は、それが表す設定することがUTF-32(UCS-4)であり、これは、ファイルを読み取るための最も簡単な方法であることを仮定

UTF-32;この例では、ファイルをUTF-16として読み取るのとは対照的に表示されています。より移植性の高い方法は、UTF-8入力ストリームからUTF-32要素への変換が保証されているので、basic_ifstream<char32_t>std::codecvt_utf8<char32_t>を明示的に使用することです。

+1

+1、私はその例を書いて、コントラストは私が行っていたものでした。 – Cubbi

+0

ああ、私は見る!ですから、常に明示的にUTF-8をより広い 'wchar_t'に変換する方が良いか、' ifstream'を使って生のUTF-8バイトをネイティブ 'char'配列に抽出するだけでよいのでしょうか? @ Cubbiの例が悪い習慣であると推測するのか、それとも単に例の範囲外であるのかを判断するのかどうかはわかりません。 – Ephemera

+0

@PLPiperはい、あなたはいつでもファイルをマルチ配列のエンコーディングに変換できます。このような配列を標準のC++で行うことはできませんが(ワイドに変換する以外には)、たくさんのライブラリがutf8の入力を受け取ります。 – Cubbi

2

あなたが使用したcppreferenceコードスニペットのアイデアは、UTF-16ファイルをUTF-16文字列に読み込む方法を示しています。なぜなら、これらのファイルはofstreamを使ってファイルを書きますが、wifstream(wchar_t) 。

関連する問題