如何在C ++ 11中将(cout
/ wcout
/ ...)char32_t打印到控制台?
以下代码打印十六进制值:
u32string s2 = U"Добрый день";
for(auto x:s2){
wcout<<(char32_t)x<<endl;
}
答案 0 :(得分:3)
首先,我不认为wcout
应该打印为char
和wchar_t
之外的任何字符。 char32_t
既不是。
以下是打印单个wchar_t's
的示例程序:
#include <iostream>
using namespace std;
int main()
{
wcout << (wchar_t)0x41 << endl;
return 0;
}
输出(ideone):
A
目前,即使在主要操作系统中,也无法在控制台中获得一致的Unicode输出。通过cout
,wcout
,printf()
,wprintf()
等简单的Unicode文本输出将无法在没有重大黑客攻击的情况下在Windows上运行。在Windows控制台中获取可读Unicode文本的问题在于能够选择正确的Unicode字体。在这方面,Windows的控制台非常破碎。请参阅this answer of mine并按照其中的链接进行操作。
答案 1 :(得分:0)
我知道这已经很老了,但是我必须自己解决它,然后您就可以解决了。 这个想法是在Unicode的UTF-8和UTF-32编码之间切换:您可以删除u8字符串,所以只需将UTF-32编码的char32_t转换为它,就可以了。这些是我想出的底层函数(没有Modern C ++)。也许这些可以被优化,也可以:任何建议都可以。
char* char_utf32_to_utf8(char32_t utf32, const char* buffer)
// Encodes the UTF-32 encoded char into a UTF-8 string.
// Stores the result in the buffer and returns the position
// of the end of the buffer
// (unchecked access, be sure to provide a buffer that is big enough)
{
char* end = const_cast<char*>(buffer);
if(utf32 < 0x7F) *(end++) = static_cast<unsigned>(utf32);
else if(utf32 < 0x7FF) {
*(end++) = 0b1100'0000 + static_cast<unsigned>(utf32 >> 6);
*(end++) = 0b1000'0000 + static_cast<unsigned>(utf32 & 0b0011'1111);
}
else if(utf32 < 0x10000){
*(end++) = 0b1110'0000 + static_cast<unsigned>(utf32 >> 12);
*(end++) = 0b1000'0000 + static_cast<unsigned>((utf32 >> 6) & 0b0011'1111);
*(end++) = 0b1000'0000 + static_cast<unsigned>(utf32 & 0b0011'1111);
} else if(utf32 < 0x110000) {
*(end++) = 0b1111'0000 + static_cast<unsigned>(utf32 >> 18);
*(end++) = 0b1000'0000 + static_cast<unsigned>((utf32 >> 12) & 0b0011'1111);
*(end++) = 0b1000'0000 + static_cast<unsigned>((utf32 >> 6) & 0b0011'1111);
*(end++) = 0b1000'0000 + static_cast<unsigned>(utf32 & 0b0011'1111);
}
else throw encoding_error(end);
*end = '\0';
return end;
}
如果需要,可以在类中,构造函数,模板中或任何您喜欢的对象中实现此功能。
在重载运算符后面加上char数组
std::ostream& operator<<(std::ostream& os, const char32_t* s)
{
const char buffer[5] {0}; // That's the famous "big-enough buffer"
while(s && *s)
{
char_utf32_to_utf8(*(s++), buffer);
os << buffer;
}
return os;
}
和u32string
std::ostream& operator<<(std::ostream& os, const std::u32string& s)
{
return (os << s.c_str());
}
使用Wikipedia上的Unicode字符运行最简单的愚蠢测试
int main()
{
std::cout << std::u32string(U"\x10437\x20AC") << std::endl;
}
导致?€
打印在(Linux)控制台上。不过,应该使用不同的Unicode字符对此进行测试...
此外,字节顺序也不同,但是我敢肯定,您可以在this处找到解决方案。