1

これに関してSOにはたくさんの質問がありますが、それらのほとんどはwstringをファイルに書き戻すことについて言及していません。たとえば、私はこれを読んで見つけました:

// open as a byte stream
std::wifstream fin("/testutf16.txt", std::ios::binary);
// apply BOM-sensitive UTF-16 facet
fin.imbue(std::locale(fin.getloc(),
    new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
// read  
std::wstring ws;
for(wchar_t c; fin.get(c); )
{
    std::cout << std::showbase << std::hex << c << '\n';
    ws.push_back(c);
}

私は書くために同様のものを試しました:

    std::wofstream wofs("/utf16dump.txt", std::ios::binary);
    wofs.imbue(std::locale(wofs.getloc(),
        new std::codecvt_utf16<wchar_t, 0x10ffff, std::consume_header>));
    wofs << ws;

しかし、それはゴミを生成します(またはNotpad ++とvimはそれを解釈できません)。タイトルで述べたように、Im on Win、ネイティブ C++、VS 2010。

入力ファイル:

t€stUTF16✡
test

これが結果です。

t€stUTF16✡
test

16 進数に変換:

0000000: 7400 ac20 7300 7400 5500 5400 4600 3100  t.. s.t.U.T.F.1.
0000010: 3600 2127 0d00 0a00 7400 6500 7300 7400  6.!'....t.e.s.t.
0000020: 0a                                       
                     ...

vimの通常の出力:

t^@¬s^@t^@U^@T^@F^@1^@6^@!'^M^@ ^@t^@e^@s^@t^@

編集:UTF8を使用してしまいました。Andrei Alexandrescu は、これが最高のエンコーディングであり、大きな損失はないと言っています。:)

4

3 に答える 3

3

あなたの同様のコードは -- そうではありません。ドキュメントに記載されているstd::ios::binaryにもかかわらず、スタイルを削除しました

バイト ストリームはバイナリ ファイルに書き込む必要があります。テキスト ファイルに書き込むと、破損する可能性があります。

ASCII モードでの NL->CRLF 変換は、2 バイトの 0x00 0x0D の代わりに 1 バイトの 0x0D を挿入するため、UTF-16 ファイルに対してはうまくいきません。

于 2012-06-08T15:37:40.927 に答える
2

標準を使用すれば簡単です(この問題を永久に解決するC++11ような追加のインクルードがたくさんあるため)。"utf8"

ただし、古い標準でマルチプラットフォーム コードを使用する場合は、このメソッドを使用してストリームを書き込むことができます。

  1. ストリームの UTF コンバーターに関する記事を読む
  2. stxutif.h上記のソースからプロジェクト に追加
  3. ファイルを ANSI モードで開き、次のように BOM をファイルの先頭に追加します。

    std::ofstream fs;
    fs.open(filepath, std::ios::out|std::ios::binary);
    
    unsigned char smarker[3];
    smarker[0] = 0xEF;
    smarker[1] = 0xBB;
    smarker[2] = 0xBF;
    
    fs << smarker;
    fs.close();
    
  4. 次に、ファイルを次のように開き、UTFそこにコンテンツを書き込みます。

    std::wofstream fs;
    fs.open(filepath, std::ios::out|std::ios::app);
    
    std::locale utf8_locale(std::locale(), new utf8cvt<false>);
    fs.imbue(utf8_locale); 
    
    fs << .. // Write anything you want...
    
于 2012-09-20T17:11:43.330 に答える
1

出力には、generate_headerの代わりに使用しますconsume_header

http://en.cppreference.com/w/cpp/locale/codecvt_modeを参照してください

于 2012-06-08T15:44:14.940 に答える