将字符串从UTF-8转换为ISO-8859-1

Convert string from UTF-8 to ISO-8859-1

本文关键字:ISO-8859-1 转换 UTF-8 字符串      更新时间:2023-10-16

我试图将UTF-8 string转换为ISO-8859-1 char*,以便在遗留代码中使用。我认为唯一的办法就是使用iconv

我绝对更喜欢一个完全基于string的c++解决方案,然后在结果字符串上调用.c_str()

我该怎么做?代码示例,如果可能的话,请。我很好使用iconv,如果它是唯一的解决方案,你知道。

我将根据另一个答案修改我的代码来实现Alf的建议。

std::string UTF8toISO8859_1(const char * in)
{
    std::string out;
    if (in == NULL)
        return out;
    unsigned int codepoint;
    while (*in != 0)
    {
        unsigned char ch = static_cast<unsigned char>(*in);
        if (ch <= 0x7f)
            codepoint = ch;
        else if (ch <= 0xbf)
            codepoint = (codepoint << 6) | (ch & 0x3f);
        else if (ch <= 0xdf)
            codepoint = ch & 0x1f;
        else if (ch <= 0xef)
            codepoint = ch & 0x0f;
        else
            codepoint = ch & 0x07;
        ++in;
        if (((*in & 0xc0) != 0x80) && (codepoint <= 0x10ffff))
        {
            if (codepoint <= 255)
            {
                out.append(1, static_cast<char>(codepoint));
            }
            else
            {
                // do whatever you want for out-of-bounds characters
            }
        }
    }
    return out;
}

无效的UTF-8输入导致字符丢失。

首先将UTF-8转换为32位Unicode。

则保留0到255之间的值

这些是拉丁-1代码点,对于其他值,决定是否要将其视为错误或可能替换为代码点127(我最喜欢的是ASCII"del")或问号或其他东西。


c++标准库定义了一个可以使用的std::codecvt专门化,

template<>
codecvt<char32_t, char, mbstate_t>

c++ 11§22.4.1.4/3: “专门化codecvt <char32_t, char, mbstate_t>在UTF-32和UTF-8编码模式

Alfs建议在c++ 11中实现

#include <string>
#include <codecvt>
#include <algorithm>
#include <iterator>
auto i = u8"H€llo Wørld";
std::wstring_convert<std::codecvt_utf8<wchar_t>> utf8;
auto wide = utf8.from_bytes(i);
std::string out;
out.reserve(wide.length());
std::transform(wide.cbegin(), wide.cend(), std::back_inserter(out),
           [](const wchar_t c) { return (c <= 255) ? c : '?'; });
// out now contains "H?llo Wxf8rld"