gpt4 book ai didi

c++ - iostreams - 打印 `wchar_t` 或 `charXX_t` 值作为字符

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:42:50 27 4
gpt4 key购买 nike

如果你输入 wchar_t , char16_t , 或 char32_t value 到一个窄的 ostream,它将打印代码点的数值。

#include <iostream>
using std::cout;
int main()
{
cout << 'x' << L'x' << u'x' << U'x' << '\n';
}

打印 x120120120 .这是因为有一个 operator<<对于basic_ostream的具体组合及其 charT , 但其他字符类型没有类似的运算符,因此它们会自动转换为 int并以这种方式打印。同样,非窄字符串文字( L"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 中完成,我将采用特定于平台的答案。

(灵感来自 this question 。)

最佳答案

如您所述,没有 operator<<(std::ostream&, const wchar_t)对于狭窄的 ostream。如果你想使用语法,你可以教 ostream如何处理 wchar s 以便该例程被选为比需要首先转换为整数的例程更好的重载。

如果你喜欢冒险:

namespace std {
ostream& operator<< (ostream& os, wchar_t wc) {
if(unsigned(wc) < 256) // or another upper bound
return os << (unsigned char)wc;
else
throw your_favourite_exception; // or handle the error in some other way
}
}

否则,做一个简单的struct透明地包含 wchar_t并且有一个自定义 friend operator<<并在输出之前将宽字符转换为宽字符。

编辑:要与语言环境进行即时转换,您可以使用 <cwchar> 中的函数,比如:

ostream& operator<< (ostream& os, wchar_t wc) {
std::mbstate_t state{};
std::string mb(MB_CUR_MAX, '\0');
size_t ret = std::wcrtomb(&mb[0], wc, &state);
if(ret == static_cast<std::size_t>(-1))
deal_with_the_error();
return os << mb;
}

不要忘记将您的语言环境设置为系统默认值:

std::locale::global(std::locale(""));
std::cout << L'ŭ';

关于c++ - iostreams - 打印 `wchar_t` 或 `charXX_t` 值作为字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41107667/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com