C ++ Windows十进制到UTF-8字符转换

我一直在使用下面的函数将Unicode字符的十进制表示转换为C ++中的UTF8字符本身。 我目前的function在Linux / Unix系统上运行良好,但在Windows上不断返回错误的字符。

void GetUnicodeChar(unsigned int code, char chars[5]) { if (code <= 0x7F) { chars[0] = (code & 0x7F); chars[1] = '\0'; } else if (code <= 0x7FF) { // one continuation byte chars[1] = 0x80 | (code & 0x3F); code = (code >> 6); chars[0] = 0xC0 | (code & 0x1F); chars[2] = '\0'; } else if (code <= 0xFFFF) { // two continuation bytes chars[2] = 0x80 | (code & 0x3F); code = (code >> 6); chars[1] = 0x80 | (code & 0x3F); code = (code >> 6); chars[0] = 0xE0 | (code & 0xF); chars[3] = '\0'; } else if (code <= 0x10FFFF) { // three continuation bytes chars[3] = 0x80 | (code & 0x3F); code = (code >> 6); chars[2] = 0x80 | (code & 0x3F); code = (code >> 6); chars[1] = 0x80 | (code & 0x3F); code = (code >> 6); chars[0] = 0xF0 | (code & 0x7); chars[4] = '\0'; } else { // unicode replacement character chars[2] = 0xEF; chars[1] = 0xBF; chars[0] = 0xBD; chars[3] = '\0'; } } 

任何人都可以提供一个替代function或修复目前的function,我正在使用,将在Windows上工作?

–UPDATE–

 INPUT: 225 OUTPUT ON OSX: á OUTPUT ON WINDOWS: ├í 

Solutions Collecting From Web of "C ++ Windows十进制到UTF-8字符转换"

你不显示你的代码打印,但大概你在做这样的事情:

 char s[5]; GetUnicodeChar(225, s); std::cout << s << '\n'; 

你在OS X上得到好的输出和在Windows上输出不好的原因是因为OS X使用UTF-8作为默认编码,而Windows使用一些传统编码。 所以当你在OS X上输出UTF-8的时候,OS X会正确地假设它是UTF-8并显示它。 在Windows上输出UTF-8时,Windows会假定(不正确)它是其他编码。

您可以使用iconv程序在Terminal.app中使用以下命令来模拟OS X上的问题

 iconv -f cp437 -t utf8 <<< "á" 

这需要UTF-8字符串,将其重新解释为使用Windows代码页面437编码的字符串,并将其转换为UTF-8以供显示。 OS X的输出是├í

为了测试小的事情,你可以做以下的事情来在Windows上正确显示UTF-8数据。

 #include <Wincon.h> #include <cstdio> char s[5]; GetUnicodeChar(225, s); SetConsoleOutputCP(CP_UTF8); std::printf("%s\n", s); 

另外,标准库的Windows实现部分不支持UTF-8的输出,因此即使在更改输出编码代码(如std::cout << s仍然无法工作。


在一个侧面说明,采取一个数组作为这样的参数:

 void GetUnicodeChar(unsigned int code, char chars[5]) { 

是一个坏主意。 这不会遇到如下错误:

 char *s; GetUnicodeChar(225, s); char s[1]; GetUnicodeChar(225, s); 

你可以通过改变函数来引用一个数组来避免这些特定的问题:

 void GetUnicodeChar(unsigned int code, char (&chars)[5]) { 

不过,一般来说,我建议完全避免原始数组。 如果你真的想要一个数组,你可以使用std::array array。 如果你想要文本,你可以使用std::string ,在这里IMO是个不错的选择:

 std::string GetUnicodeChar(unsigned int code); 

该功能是正确的。 输出可能不是,这意味着该例程中有一个错误。 但你不显示它。 我敢打赌,你认为Windows可以打印UTF-8。