c++ Windows十进制到UTF-8字符转换
C++ Windows decimal to UTF-8 Character Conversion
我一直在使用下面的函数将unicode字符的十进制表示转换为c++中的UTF8字符本身。我现在的功能在Linux/Unix系统上运行良好,但它在Windows上一直返回错误的字符。
void GetUnicodeChar(unsigned int code, char chars[5]) {
if (code <= 0x7F) {
chars[0] = (code & 0x7F); chars[1] = ' ';
} else if (code <= 0x7FF) {
// one continuation byte
chars[1] = 0x80 | (code & 0x3F); code = (code >> 6);
chars[0] = 0xC0 | (code & 0x1F); chars[2] = ' ';
} 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] = ' ';
} 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] = ' ';
} else {
// unicode replacement character
chars[2] = 0xEF; chars[1] = 0xBF; chars[0] = 0xBD;
chars[3] = ' ';
}
}
谁能提供一个替代功能或修复我正在使用的当前功能,将在Windows上工作?
——更新
INPUT: 225
OUTPUT ON OSX: á
OUTPUT ON WINDOWS: á
您没有显示用于打印的代码,但是您可能正在做这样的事情:
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会(错误地)认为它是其他编码。
您可以在Terminal.app
中使用以下命令使用iconv
程序在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("%sn", 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
,在我看来这是一个很好的选择:
std::string GetUnicodeChar(unsigned int code);
函数正确。输出可能不是,这意味着该例程中存在错误。但你没有表现出来。我敢打赌你认为Windows可以打印UTF-8。
- 从矢量<无符号字符>转换为字符* 包括垃圾数据
- 尝试将字符串/字符转换为整数会产生意外结果
- 如何使用C++将字符串中的字符转换为整数变量
- 字符转换功能 std::isupper() & std::islower() C++17
- 将字符 * 转换为字符串 *
- 在编译时将常量字符* 转换为常量 char_type*
- 如何在 C/C++ 中将无符号字符*转换为无符号字符数组?
- 错误:请求从"常量字符 [5]"转换为非标量类型"字符串"
- 无法使用字符串流将字符转换为字符串C++
- 将无符号字符 C++ 转换为 C#
- C++:使用没有位移位的指针将无符号字符转换为无符号 int
- 为什么我可以隐式地将字符*转换为常量字符*,但不能将无符号字符*
- 无法<string>从"常量字符 []"转换为<类名>
- 不能将字符转换为整数吗?
- 编译时将字符*转换为字节
- CP1251:从字符* 转换为 wchar_t* 时的编码失真
- 将单个字符转换为 std::string 前缀 \x01
- PPM 将字符转换为 int 授予负数
- 通过像printf这样的可变参数函数传递一个带有常量字符*转换函数的类
- 将常量字符* 转换为字符时出错