iconv 编码gb2312转utf8 转码失败的坑

使用背景

项目中使用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;
}

使用iconv进行编码gb2312转utf8 转码失败的坑的更多相关文章

  1. UTF8转换为GB编码gb2312转换为utf-8

    这个方法是用windows的字符集转换的,跟sybase 的unicode码表可能在某些符号上有差别,对于大部分字符来说,尤其是 汉字,应该不会有问题的,如果要求比较高的话,可以买sybase的 un ...

  2. C#获取文本文件的编码,自动区分GB2312和UTF8

    C# 获取文本文件的编码,自动区分GB2312和UTF8 以下是获取文件编码的一个类 using System; using System.IO; using System.Text; /// < ...

  3. 网络编码 GB2312、GBK与UTF-8的区别

    GB2312.GBK与UTF-8的区别  这是一个异常经典的问题,有无数的新手站长每天都在百度这个问题,而我,作为一个“伪老手”站长,在明白这个这个问题的基础上,有必要详细的解答一下.  首先,我们要 ...

  4. 字符编码(ASCII、ANSI、GB2312、UTF-8等)系统梳理

    引言 在显示器上看见的文字.图片等信息在电脑里面其实并不是我们看见的样子,即使你知道所有信息都存储在硬盘里,把它拆开也看不见里面有任何东西,只有些盘片.假设,你用显微镜把盘片放大,会看见盘片表面凹凸不 ...

  5. 字符编码(ASCII、ANSI、GB2312、UTF-8等)系统梳理(转载)

    引言 在显示器上看见的文字.图片等信息在电脑里面其实并不是我们看见的样子,即使你知道所有信息都存储在硬盘里,把它拆开也看不见里面有任何东西,只有些盘片.假设,你用显微镜把盘片放大,会看见盘片表面凹凸不 ...

  6. 采集的时候,列表的编码是gb2312,内容页的编码却是UTF-8,这种网站怎么采集?

    采集的时候,列表的编码是gb2312,内容页的编码却是UTF-8,这种网站怎么采集? 采集的时候,列表的编码是UTF-8,内容页的编码却是gb2312,这种网站怎么采集? 这种情况怎么解决呢? 哈哈哈 ...

  7. 各种编码UNICODE、UTF-8、ANSI、ASCII、GB2312、GBK详解

    来自:http://blog.csdn.net/lvxiangan/article/details/8151670 ------------------------------------------ ...

  8. 编码介绍(ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE)

    转载:http://blog.jobbole.com/30526/(前面内容)和http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf ...

  9. 编码的来源于格式简介ANSI、GBK、GB2312、UTF-8、GB18030和 UNICODE

    编码一直是让新手头疼的问题,特别是 GBK.GB2312.UTF-8 这三个比较常见的网页编码的区别,更是让许多新手晕头转向,怎么解释也解释不清楚.但是编码又是那么重要,特别在网页这一块.如果你打出来 ...

随机推荐

  1. 消息中间件——RabbitMQ

    RabbitMQ介绍 RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性.扩展性.高可用性等方面表现不俗.RabbitM ...

  2. day_2安装Python解释器和pycharm

    首先我们复习一下昨天的内容 ···重点 1:进制转换:二进制 与 十六进制 1111  0101 1010 转换为 f5a 2:内存分布:堆区 和 栈区 计算机的原理: 控制器 运算器 存储器 inp ...

  3. bash编程-Shell变量

    bash中,所有变量的值默认均为字符串. 1. 变量操作 调用变量 $变量 查看变量(所有类型) set 删除变量 unset 变量 2. 变量分类 2.1 自定义变量 自定义变量仅对当前Shell有 ...

  4. 给JavaScript24条最佳实践

    作为“30 HTML和CSS最佳实践”的后续,这篇文章将回顾JavaScript的知识 !如果你看完了下面的内容,请务必让我们知道你掌握的小技巧! 1.使用 === 代替 == JavaScript ...

  5. Android 和 iOS 实现录屏推流的方案整理

    一.录屏推流实现的步骤 1. 采集数据 主要是采集屏幕获得视频数据,采集麦克风获得音频数据,如果可以实现的话,我们还可以采集一些应用内置的音频数据. 2. 数据格式转换 主要是将获取到的视频和音频转换 ...

  6. Testing - 软件测试知识梳理 - 测试分类

    参考信息 软件测试分类 经典软件测试技术分类 软件测试方法汇总 简洁分类 对软件内部结构的深入程度 黑盒测试:又叫功能测试.数据驱动测试或基于需求规格说明书的功能测试. 该测试类别注重于测试软件的功能 ...

  7. js 解析url中search时存在中文乱码问题解决方案

    一 问题出现原因 当存在这样一种需求,前端需要通过url中search返回值进行保存使用,但如果search中存在中文解析出来会导致乱码.这个问题我找了很久原因,最后终于知道解决方案,这里和大家分享一 ...

  8. String-intern方法举例分析其含义

    之后重新理解这个知识点时,又写了一些小例子 String a1 = new String("str01") ; String a2 = "str01" ; Sy ...

  9. mint-ui Infinite scroll 重复加载、加载无效的原因及解决方案

    1.无限滚动的运用场景: 一般运用在列表展示,有分页.下拉加载更多的需求中. 2.代码分析 代码很简单,实现了列表分页,数据加载完之后显示数据状态 <template> <div c ...

  10. AcceptEx与完成端口(IOCP)结合实例

    前言 在windows平台下实现高性能网络服务器,iocp(完成端口)是唯一选择.编写网络服务器面临的问题有:1 快速接收客户端的连接.2 快速收发数据.3 快速处理数据.本文主要解决第一个问题. A ...