手机版
你好,游客 登录 注册
背景:
阅读新闻

使用iconv进行编码gb2312转utf8 转码失败及解决

[日期:2019-07-28] 来源:Linux社区  作者:chencarl [字体: ]

使用背景

项目中使用thrift进行C#程序调用c++接口,其中的协议是通过json进行传输的,由于默认thrift使用utf8进行传输,而C#和c++程序都默认使用多字节的编码方式,所以在传输前就需要对编码进行utf8的转换,而在接收处理的时候再转换成gb2312。

问题

bug发生在一个文件路径上面,包含文件路径就会导致c++端无法解析,但是纯中文和英文及不同字符都没有问题,所以一开始未怀疑是编码问题,经过调试最终确定问题在iconv转码上,在转码的时候转换失败,导致返回结果为空。

分析

文件名为"1癵鰢⑷}·ˇ々.mp4",其中包含有特殊汉字和字符,猜测为字符集无法表示导致转码失败。

解决

网上查询确实存在该问题,建议将编码gb2312换成 gb18030 以支持更多字符。

原来的转码函数
std::string ConvertCode::gbk2utf8(const std::string& strGbk)
{
    return code_convert("gb2312", "utf-8", strGbk);
}

转变以后测试正常
std::string ConvertCode::gbk2utf8(const std::string& strGbk)
{
    return code_convert("gb18030", "utf-8", strGbk);
}

附iconv转变函数
std::string ConvertCode::code_convert(char *source_charset, char *to_charset, const std::string& sourceStr)
{
    iconv_t cd = iconv_open(to_charset, source_charset);//获取转换句柄,void*类型
    if (cd == 0)
        return "";

    size_t inlen = sourceStr.size();

    if (inlen == 0)
        return "";

    size_t outlen = inlen*2+1;
    const char* inbuf = (char*)sourceStr.c_str();
    char* outbuf = (char*)malloc(outlen);
    memset(outbuf, 0, outlen);
    char *poutbuf = outbuf; //多加这个转换是为了避免iconv这个函数出现char(*)[255]类型的实参与char**类型的形参不兼容
    if (iconv(cd, &inbuf, &inlen, &poutbuf, &outlen) == -1)
        return "";

    std::string strTemp(outbuf);//此时的strTemp为转换编码之后的字符串
    iconv_close(cd);
    return strTemp;
}

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

本文永久更新链接地址https://www.linuxidc.com/Linux/2019-07/159632.htm

linux
相关资讯       iconv  gb2312转utf8 
本文评论   查看全部评论 (0)
表情: 表情 姓名: 字数

       

评论声明
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款