我尝试将UTF-8 string
转换为ISO-8859-1 char*
,以便在遗留代码中使用。我实现这一目标的唯一方法是使用iconv
。
我肯定更喜欢完全基于string
的C ++解决方案,然后只在结果字符串上调用.c_str()
。
我该怎么做?请尽可能使用代码示例。如果它是您知道的唯一解决方案,我可以使用iconv
。
答案 0 :(得分:11)
我将修改我的代码from another answer以实施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输入会导致字符丢失。
答案 1 :(得分:6)
首先将UTF-8转换为32位Unicode。
然后保留0到255范围内的值。
这些是Latin-1代码点,对于其他值,决定是将其视为错误还是替换为代码点127(my fav,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编码方案“
答案 2 :(得分:2)
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 W\xf8rld"