如何在c++多平台中将(char *)从ISO-8859-1转换为UTF-8

How to convert (char *) from ISO-8859-1 to UTF-8 in C++ multiplatformly?

本文关键字:ISO-8859-1 转换 UTF-8 char c++ 平台      更新时间:2023-10-16

我正在用c++修改一个软件,该软件处理ISO Latin 1格式的文本,将数据存储在SQLite中的数据库中。
问题是SQLite工作在UTF-8…使用相同数据库的Java模块在UTF-8下工作。

我想在存储到数据库之前有一种方法将ISO Latin 1字符转换为UTF-8字符。我需要它在Windows和Mac上工作。

我听说重症监护室会这样做,但我认为它太臃肿了。我只需要一个简单的转换系统(最好是来回)为这2个字符集。

我该怎么做呢?

ISO-8859-1被纳入ISO/IEC 10646和Unicode的前256个码位。所以转换非常简单。

对应每个字符:

uint8_t ch = code_point; /* assume that code points above 0xff are impossible since latin-1 is 8-bit */
if(ch < 0x80) {
    append(ch);
} else {
    append(0xc0 | (ch & 0xc0) >> 6); /* first byte, simplified since our range is only 8-bits */
    append(0x80 | (ch & 0x3f));
}

详情见http://en.wikipedia.org/wiki/UTF-8#Description

EDIT:根据ninjalj的注释,latin-1直接翻译为前256个unicode码位,因此上述算法应该可以工作。

TO c++ i use this:

std::string iso_8859_1_to_utf8(std::string &str)
{
    string strOut;
    for (std::string::iterator it = str.begin(); it != str.end(); ++it)
    {
        uint8_t ch = *it;
        if (ch < 0x80) {
            strOut.push_back(ch);
        }
        else {
            strOut.push_back(0xc0 | ch >> 6);
            strOut.push_back(0x80 | (ch & 0x3f));
        }
    }
    return strOut;
}

如果通用字符集框架(如iconv)对您来说过于臃肿,请使用自己的字符集框架。

编写一个静态翻译表(从字符到UTF-8序列),将自己的翻译组合在一起。根据您使用的字符串存储(字符缓冲区,或std::string或其他),它看起来会有所不同,但其思想是-滚动源字符串,将代码超过127的每个字符替换为其UTF-8对应字符串。由于这可能会增加字符串的长度,因此在适当的位置执行此操作将非常不方便。为了获得额外的好处,您可以在两次传递中完成此操作:第一次传递确定必要的目标字符串大小,第二次传递执行转换。

如果您不介意做额外的复制,您可以将ISO Latin 1字符"拓宽"为16位字符,从而获得UTF-16。然后,您可以使用UTF8-CPP之类的东西将其转换为UTF-8。

事实上,我认为UTF8-CPP甚至可以直接将ISO Latin 1转换为UTF-8 (utf16to8函数),但您可能会收到警告。

当然,它需要真正的ISO Latin 1,而不是Windows CP 1232。