在C/C++中将ISO-8859-1字符串转换为UTF-8

gor*_*nwd 21 c c++

你会认为这很容易获得,但我很难找到一个简单的库函数,它将C或C++字符串从ISO-8859-1编码转换为UTF-8.我正在读取8位ISO-8859-1编码的数据,但需要将其转换为UTF-8字符串,以便在SQLite数据库和最终的Android应用程序中使用.

我发现了一种商业产品,但这次超出了我的预算.

R..*_*R.. 37

如果您的源编码始终是ISO-8859-1,这是微不足道的.这是一个循环:

unsigned char *in, *out;
while (*in)
    if (*in<128) *out++=*in++;
    else *out++=0xc2+(*in>0xbf), *out++=(*in++&0x3f)+0x80;
Run Code Online (Sandbox Code Playgroud)

为了安全起见,您需要确保输出缓冲区是输入缓冲区的两倍,或者包括大小限制并在循环条件下检查它.

  • 这当然回答了这个问题.但正如我在上面的评论中所说,人们会*发送给你的CP-1252错误标记为ISO-8859-1.网络服务器是我绊倒的例子,说服了我这个问题,还有文本编辑器声称在它们不是时会保存为"Latin-1"."如果你的源代码编码永远是ISO-8859-1"是一个非常大的"如果",并且可能很难追查并消除负责任的歹徒. (9认同)
  • 从可维护性的角度来看,这是非常糟糕的代码.使用更多大括号. (5认同)
  • 哇.这非常有帮助!我还没有期待另一种表查找算法.现在为ANSEL-to-UTF-8 ...... (3认同)
  • @gordon:我对ANSEL不熟悉,但是您应该知道ISO-8859-1是“唯一的”旧编码,可以很容易地转换为UTF-8。其他所有内容都需要查找表。史蒂夫(Steve)说,我的“如果..”是“大” if。 (2认同)
  • @Nick:是的,我的意思是0xA0,只是在我的脑海中错误地转换为十进制。评论太旧了,无法编辑。 (2认同)

小智 10

对于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;
}
Run Code Online (Sandbox Code Playgroud)


Spa*_*ose 5

您可以使用 boost::locale 库:

http://www.boost.org/doc/libs/1_49_0/libs/locale/doc/html/charset_handling.html

代码如下所示:

#include <boost/locale.hpp>
std::string utf8_string = boost::locale::conv::to_utf<char>(latin1_string,"Latin1");
Run Code Online (Sandbox Code Playgroud)