如果您将,或值提供给窄ostream,则它将打印代码点的数字值。
打印
#include <iostream>
using std::cout;
int main()
{
cout << 'x' << L'x' << u'x' << U'x' << '\n';
}
打印
x120120120
。这是因为特定组合的 basic_ostream
和其 charT
有一个 operator<<
,但其他字符类型没有类似的运算符,所以它们会被静默转换为 int
并以这种方式打印。同样,非窄字符串文字 (L"x"
, u"x"
, U"X"
) 将被静默转换为 void*
并作为指针值打印,而非窄字符串对象 (wstring
, u16string
, u32string
) 甚至无法编译。
那么问题来了:在窄 ostream 上以字符形式而不是代码点数值打印 wchar_t
、char16_t
或 char32_t
值,最少可怕的方法是什么?它应正确地将 所有 可表示为 ostream 编码的代码点转换为该编码,并在代码点不可表示时报告错误。(例如,给定 u'…'
和一个 UTF-8 ostream,则应将三字节序列 0xE2 0x80 0xA6 写入流; 但是,如果给定 u'â'
和一个 KOI8-R ostream,则应报告错误。)
类似地,如何在窄 ostream 上打印非窄 C-字符串或字符串对象,并将其转换为输出编码?
如果这不能在 ISO C++11 中完成,则接受特定平台的答案。
(灵感来自这个问题。)
std::wstring_convert
,或使用类似 ICONV 或 ICU 的库。 - Remy Lebeau