使用带有_O_U8TEXT的setmode来处理unicode时C ++崩溃

时间:2017-07-21 08:13:38

标签: c++ windows utf-8 crash visual-studio-2017

我试图打印unicode

_setmode(_fileno(stdout), _O_U8TEXT);
string str = u8"unicode 한글 hangul";
cout << str << endl;

我使用setmode正确显示和获取unicode,但它与Debug Assertion Fail崩溃。

然而,

_setmode(_fileno(stdout), _O_U16TEXT);
wstring str = L"unicode 한글 hangul";
wcout << str << endl;

_O_U16TEXT正确编译和打印。

如何使用UTF-8?我必须找到另一个技巧吗?

1 个答案:

答案 0 :(得分:1)

_setmode提及_O_U8TEXT_O_U16TEXT(最后),但没有详细说明他们的所作所为。它确实声明这些是翻译模式

_wsopen列表的文档(强调我的):

_O_U16TEXT
以Unicode UTF-16模式打开文件 _O_U8TEXT
以Unicode UTF-8模式打开文件

这意味着:当使用unicode io工具(wprintfstd::wcout等)时,这意味着使用unicode(UTF-16)字符串,输出将被转换为UTF -16或UTF-8,当它们被写入文件时。

试试这个:

_setmode(_fileno(stdout), _O_U8TEXT);
std::wcout << L"unicode 한글 hangul\n";

你不应该在控制台上看到差异,但如果你重定向输出:

> u8out | hexdump -C
00000000  75 6e 69 63 6f 64 65 20  ed 95 9c ea b8 80 20 68  |unicode ...... h|
00000010  61 6e 67 75 6c 0d 0a                              |angul..|
00000017

> u16out | hexdump -C
00000000  75 00 6e 00 69 00 63 00  6f 00 64 00 65 00 20 00  |u.n.i.c.o.d.e. .|
00000010  5c d5 00 ae 20 00 68 00  61 00 6e 00 67 00 75 00  |\... .h.a.n.g.u.|
00000020  6c 00 0d 00 0a 00                                 |l.....|
00000026

从理论上讲,这应该意味着你也可以_O_U8TEXT使用stdin来阅读UTF-8输入,但实际上并不总是有效:

> u8in < u8.txt
unicode 한글 hangul €µöäüß

> u8in
unicode 한글 hangul €µöäüß
unicode ?? hangul ?攄��

_O_U16TEXT 出现以使用控制台输入(在我的机器上),但是您无法使用UTF-8编码的重定向输入/输出:

> u16in
unicode 한글 hangul €µöäüß
unicode 한글 hangul €µöäüß

您可以在此处详细了解:Conventional wisdom is retarded, aka What the @#%&* is _O_U16TEXT?

PS:断言告诉你的是不能使用带有ANSI输出功能的unicode输出。奇怪的是,如果你没有设置其中一种unicode模式,那就不会强制实施,但是......