1
4

1 に答える 1

3

これは\u20ac、ASCII 文字列の Unicode 文字リテラルである which を使用しているためです。

MSVCは 4 つのナロー文字"\xe2\x82\xac\u20ac"としてエンコードします。ユーロ文字を標準の1252 コードページ0xe2, 0x82, 0xac, 0x80,にマップしたため、基本的に 0x80 としてエンコードされます。\u20ac

GCC は Unicode リテラル/u20acを 3 バイトの UTF-8 シーケンスに変換している0xe2, 0x82, 0xacため、結果の文字列は0xe2, 0x82, 0xac, 0xe2, 0x82, 0xac.

使用するstd::wstring = L"\xe2\x82\xac\u20ac"と、MSVC によって0xe2, 0x00, 0x82, 0x00, 0xac, 0x00, 0xac, 0x204 ワイド文字としてエンコードされますが、手動で作成した UTF-8 と UTF-16 を混在させているため、結果の文字列はあまり意味がありません。a を使用するstd::wstring = L"\u20ac\u20ac"と、予想どおり、ワイド文字列で 2 つの Unicode 文字が取得されます。

次の問題は、MSVC の ofstream と wofstream が常に ANSI/ASCII で記述されることです。UTF-8 で書き込むには、次を使用する必要があります<codecvt>(VS 2010 以降):

#include <string>
#include <fstream>
#include <iomanip>
#include <codecvt>

int main()
{
    std::wstring s = L"\u20ac\u20ac";

    std::wofstream out("test.txt");
    std::locale loc(std::locale::classic(), new std::codecvt_utf8<wchar_t>);
    out.imbue(loc);

    out << s.length() << L":" << s << std::endl;
    out << std::endl;
    out.close();
}

そしてUTF-16(より具体的にはUTF-16LE)を書くには:

#include <string>
#include <fstream>
#include <iomanip>
#include <codecvt>

int main()
{
    std::wstring s = L"\u20ac\u20ac";

    std::wofstream out("test.txt", std::ios::binary );
    std::locale loc(std::locale::classic(), new std::codecvt_utf16<wchar_t, 0x10ffff, std::little_endian>);
    out.imbue(loc);

    out << s.length() << L":" << s << L"\r\n";
    out << L"\r\n";
    out.close();
}

注: UTF-16 では、破損を避けるためにテキスト モードではなくバイナリ モードを使用する必要がstd::endlありL"\r\n"ます。

于 2014-08-01T06:47:41.570 に答える