小C

每天叫醒我的不只是闹钟,还有梦想。。。
随笔 - 2, 文章 - 0, 评论 - 0, 引用 - 0
数据加载中……

Linux下iconv函数的使用-编码转换

在代码中遇到需要将不同编码进行转换的问题,同事提示使用iconv函数来实现转换,自己就查了一下函数介绍开始使用,本以为很简单的函数调用即可,中间却出了一个小小的问题,记录一下,学习之
自定义函数对转换函数的封装
 1 // 对系统iconv进行包装的函数
 2 int scsIconv(string &strSou, string &strDest)
 3 {
 4     // 初始化转换函数
 5     iconv_t hIconv = 
 6         iconv_open(g_strDestCharSet.c_str(), g_strSouCharSet.c_str());
 7     if (hIconv == (iconv_t)-1)
 8     {
 9         return -1;
10     }
11     
12     // 获取源数据
13     size_t nSouSize = strSou.size();
14     char *pcInBuf = (char*)malloc(strSou.size() + 1);
15     memset(pcInBuf, 0, strSou.size() + 1);
16     memcpy(pcInBuf, strSou.c_str(), strSou.size());
17     char *pcIn = pcInBuf;
18     
19     // 开辟目的存储空间
20     size_t nDestSize = TRANS_OUT_BUF_DEF_SIZE > 2 * nSouSize ? 
21     TRANS_OUT_BUF_DEF_SIZE : 2 * nSouSize;
22     char *pcOutBuf = (char*)malloc(nDestSize);
23     if (!pcOutBuf)
24     {
25         free(pcInBuf);
26         return -1;
27     }
28     char *pcOut = pcOutBuf;
29     
30     // 开始转换
31     size_t nRet;
32     do
33     {
34         memset(pcOutBuf, 0, nDestSize);
35         nRet = iconv(hIconv, &pcIn, &nSouSize, &pcOut, &nDestSize);
36         if (nRet == (size_t)-1)
37         {
38             if (errno == E2BIG)
39             {
40                 pcOutBuf = (char*)realloc(pcOutBuf, 2 * nDestSize);
41                 if (!pcOutBuf)
42                 {
43                     free(pcInBuf);
44                     return -1;
45                 }
46                 pcIn = pcInBuf;
47                 pcOut = pcOutBuf;
48                 
49                 nDestSize = 2 * nDestSize;
50             }
51             else
52             {
53                 free(pcInBuf);
54                 return -1;
55             }
56         }
57         else
58         {
59             strDest = pcOutBuf;
60             break;
61         }
62     }while (1);
63     
64     free(pcInBuf);
65     free(pcOutBuf);
66     return 0;
67 }
那个小小的问题就出在iconv对源数据地址和目的数据地址的处理上,iconv执行之后对修改源数据地址和目的数据地址,简单来说就是,在iconv中会一步一步的向后移动这两个指针的指向位置,当转换结束后,均指向各自缓冲区的结尾处,因此取数据时需要注意。应该将原来的目的地址拷贝一份,以用在转换后取数据。
下面是我调试时的信息
图片中用红线圈起来的值体现了上面所说的iconv对源地址和目的地址的具体修改,
执行iconv后的pcIn和执行前的pcIn相差的值正好等于nSouSize的大小即源数据的字节数86。
执行iconv后的pcOut和执行前的pcOut相差值正好等于nDestSize前后的差值为90。
这里的90和86是因为转换中只有4个中文字符,所以,长度增加了4。

posted on 2014-10-15 18:45 冷冰若水 阅读(3521) 评论(0)  编辑 收藏 引用 所属分类: C/C++


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理