1 に答える
これは\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, 0x20
4 ワイド文字としてエンコードされますが、手動で作成した 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"
ます。