5

我正在更改 C++ 中的软件,该软件以 ISO Latin 1 格式处理文本,以将数据存储在 SQLite 的数据库中。
问题是 SQLite 在 UTF-8 中工作......而使用相同数据库的 Java 模块在 UTF-8 中工作。

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

我听说ICU会这样做,但我认为它太臃肿了。对于这两个字符集,我只需要一个简单的转换系统(最好是来回转换)。

我该怎么做?

4

4 回答 4

17

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 。

编辑:根据ninjalj的评论,latin-1 将直接转换为前 256 个 unicode 代码点,因此上述算法应该可以工作。

于 2011-04-07T19:43:34.060 回答
2

对于 c++,我使用这个:

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;
}
于 2016-10-05T21:19:03.863 回答
1

If general-purpose charset frameworks (like iconv) are too bloated for you, roll your own.

Compose a static translation table (char to UTF-8 sequence), put together your own translation. Depending on what do you use for string storage (char buffers, or std::string or what) it would look somewhat differently, but the idea is - scroll through the source string, replace each character with code over 127 with its UTF-8 counterpart string. Since this can potentially increase string length, doing it in place would be rather inconvenient. For added benefit, you can do it in two passes: pass one determines the necessary target string size, pass two performs the translation.

于 2011-04-07T19:16:44.080 回答
0

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

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

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

于 2011-04-07T19:31:47.860 回答