我一直在使用下面的函数将unicode字符的十进制表示转换为C ++中的UTF8字符本身。我目前的功能在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';
}
}
任何人都可以为我正在使用的当前功能提供替代功能或修复程序吗?
- UPDATE -
INPUT: 225
OUTPUT ON OSX: á
OUTPUT ON WINDOWS: á
答案 0 :(得分:5)
您不会显示打印代码,但可能您正在执行以下操作:
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
程序在终端.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
。如果你想要文本,你可以使用std::string
,这里IMO是个不错的选择:
std::string GetUnicodeChar(unsigned int code);
答案 1 :(得分:2)
功能正确。输出大概不是,这意味着该例程中存在一个错误。但是你没有表现出来。我打赌你假设Windows可以打印UTF-8。