微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

我一直在使用下面的函数将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';
    }
}

任何人都可以提供替代功能或修复我正在使用的当前功能,将在Windows上运行吗?

–UPDATE–

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会(错误地)假定它是其他编码.

您可以使用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.如果你想要文本,你可以使用std :: string,这里IMO是个不错的选择:

std::string GetUnicodeChar(unsigned int code);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐