zwo*_*wol 6 c++ iostream widechar
如果将a wchar_t,char16_t或char32_t值提供给狭窄的ostream,它将打印代码点的数值.
#include <iostream>
using std::cout;
int main()
{
cout << 'x' << L'x' << u'x' << U'x' << '\n';
}
Run Code Online (Sandbox Code Playgroud)
打印x120120120.这是因为有一个与它operator<<的特定组合,但是对于其他字符类型没有类似的运算符,所以它们以这种方式静默转换和打印.类似地,非窄字符串(,,)将被默默地转换为与打印为指针值,和非窄字符串对象(,,)甚至不会编译.basic_ostreamcharTintL"x"u"x"U"X"void*wstringu16stringu32string
因此,问题:什么是打印最少可怕的方式wchar_t,char16_t或char32_t在一个狭窄的ostream值,作为字符,而不是作为码点的数值?它应该正确地将在ostream的编码中可表示的所有代码点转换为该编码,并且应该在代码点不可表示时报告错误.(例如,给定u'…'和UTF-8 ostream,应将三字节序列0xE2 0x80 0xA6写入流;但是给定u'â'和KOI8-R ostream,应报告错误.)
同样,如何在狭窄的ostream上打印非窄C字符串或字符串对象,转换为输出编码?
如果在ISO C++ 11中无法做到这一点,我将采用特定于平台的答案.
(灵感来自这个问题.)
正如您所指出的,没有operator<<(std::ostream&, const wchar_t)狭窄的 ostream。但是,如果您想使用该语法,您可以教ostream如何使用wchars,以便将该例程选为比首先需要转换为整数的例程更好的重载。
如果您喜欢冒险:
\n\nnamespace std {\n ostream& operator<< (ostream& os, wchar_t wc) {\n if(unsigned(wc) < 256) // or another upper bound\n return os << (unsigned char)wc;\n else\n throw your_favourite_exception; // or handle the error in some other way\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n否则,制作一个透明struct包含 awchar_t并具有自定义的简单字符friend operator<<,并在输出之前将宽字符转换为该字符。
编辑:要与语言环境进行即时转换,您可以使用 中的函数<cwchar>,例如:
ostream& operator<< (ostream& os, wchar_t wc) {\n std::mbstate_t state{};\n std::string mb(MB_CUR_MAX, \'\\0\');\n size_t ret = std::wcrtomb(&mb[0], wc, &state);\n if(ret == static_cast<std::size_t>(-1))\n deal_with_the_error();\n return os << mb;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n不要忘记将您的区域设置设置为系统默认值:
\n\nstd::locale::global(std::locale(""));\nstd::cout << L\'\xc5\xad\';\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |