Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将字符串从UTF-8转换为ISO-8859-1_C++_Utf 8_Iso 8859 1_Iconv - Fatal编程技术网

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

C++ 将字符串从UTF-8转换为ISO-8859-1,c++,utf-8,iso-8859-1,iconv,C++,Utf 8,Iso 8859 1,Iconv,我正在尝试将UTF-8字符串转换为ISO-8859-1char*,以便在遗留代码中使用。我唯一能做到这一点的方法就是用 我肯定更喜欢完全的字符串< /COD>基于C++的解决方案,然后只调用生成的字符串上的 .cString()/ 我该怎么做?如果可能,请提供代码示例。如果这是您知道的唯一解决方案,我可以使用iconv。首先将UTF-8转换为32位Unicode 然后将值保持在0到255之间 这些是拉丁1代码点,对于其他值,请决定是否将其视为错误,或者用代码点127(我的fav,ASCII“d

我正在尝试将UTF-8
字符串
转换为ISO-8859-1
char*
,以便在遗留代码中使用。我唯一能做到这一点的方法就是用

我肯定更喜欢完全的字符串< /COD>基于C++的解决方案,然后只调用生成的字符串上的<代码> .cString()/<代码>


我该怎么做?如果可能,请提供代码示例。如果这是您知道的唯一解决方案,我可以使用iconv。

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

然后将值保持在0到255之间

这些是拉丁1代码点,对于其他值,请决定是否将其视为错误,或者用代码点127(我的fav,ASCII“del”)或问号或其他内容替换


C++标准库定义了一个<代码> STD::CODECVT< < /代码>专业化,可以使用,

template<>
codecvt<char32_t, char, mbstate_t>
模板
编解码器
C++11§22.4.1.4/3:“专业化
codevt
在UTF-32和
UTF-8编码方案“

我将修改我的代码以实现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;
}
std::字符串UTF8toISO8859_1(常量字符*in)
{
std::字符串输出;
if(in==NULL)
返回;
无符号整数码点;
而(*in!=0)
{
无符号字符ch=静态_转换(*in);

if(chAlfs建议在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"
#包括
#包括
#包括
#包括
自动i=u8“H€llo Wørld”;
std::wstring_转换utf8;
自动宽度=utf8。从_字节(i);
std::字符串输出;
out.reserve(宽.length());
std::transform(wide.cbegin()、wide.cend()、std::back_插入器(out),

[C](const WCARGATT C){返回(C听起来像是一个潜在的大项目),而恰好是像Iconv这样一个库所适合的东西。正确的做法有什么不对?如果这是唯一可用的方式,我很好用Iconv。它绝对不是最优雅的C++解决方案。像代码> StoToIP。“ISO-8859-1”)
将更加优雅。我的观点是,即使我在iconv中使用它,我也不清楚如何将库与
字符串
输入一起使用。不确定,但可能会有帮助:这很好,因为Unicode最初被定义为ISO-8859-1的超集。请参阅P.S.作为转换的起点,我可能会建议您这样做但是,但是,
std::codecvt
不是在C++17中被弃用了吗?事实上,我有了UTF-8
string
。如果你把它改成了
string
,那就太完美了。@ChrisRedford,用
mystr.C_str()调用它就好了
。我喜欢使用
const char*
输入,因为它更灵活。由于输入来自
std::string
,只需将
const char*in
替换为
const std::string&in
,然后创建一个在.c_str()中分配的本地
char*
变量
用于循环中,并使用
in.size()
作为循环计数器,而不是
*in!=0
。或者使用
in.begin()
in.end()
迭代器。如果您正在寻找一种将带有utf-8字符的std::string转换为iso 8859或Windows 1252编码的方法,这里有一个函数可以使用硬编码转换,不调用codecvt_utf8()、iconv()或者类似的函数。它使用一个类似的Mark-Ransom循环。@GustavoRodríguez这很容易做到,因为Unicode的前256个代码点采用了拉丁-1字符集,无需翻译。