使用libiconv进行GBK和UTF-8的转换

libiconv中的iconv函数是个很容易误用的函数,如果不仔细看iconv.h头文件中说明,按照习惯用法来用,基本上只能莫名其妙百思而不得其解了。

size_t iconv (iconv_t cd,  char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft);

大眼一看这个方法,肯定以为第一个是句柄,第二个是要转换的源字符串开头,第3个是源字节串长度,第4个是转换后保存结果的缓冲区,第5个是转换的结果的长度。

于是就用了,于是就出现段错误或者错误的结果……。

仔细看了看说明

/* Converts, using conversion descriptor ‘cd’, at most ‘*inbytesleft’ bytes
   starting at ‘*inbuf’, writing at most ‘*outbytesleft’ bytes starting at
   ‘*outbuf’.
   Decrements ‘*inbytesleft’ and increments ‘*inbuf’ by the same amount.
   Decrements ‘*outbytesleft’ and increments ‘*outbuf’ by the same amount.
*/

才晓得第二个参数是源字符串开头没错,但iconv运行后,会改变*inbuf的值,同样也会增加*outbuf的值,也会减小*inbytesleft和*outbytesleft的值。

仔细看这些变量的名字,也能理解为什么是bytesleft而不是byteslen。所以第5个参数*outbytesleft对应的对象为保存结果的缓冲区的容量长度。一般初始化为源字符串长度的2倍即可。


#include <stdio.h>
#include "iconv.h"


int main(int argc, char** argv)
{
 int ret = 0;
 char* strGB = "我是中国";
 int lenSrc = strlen(strGB);
 int lenDst = lenSrc*5;
 printf("lenDst=%d\n", lenDst);
 char* out  = (char*) malloc(lenDst);
 char* pFreeOut = out;
 iconv_t cd = iconv_open("UTF-8", "GBK");
 printf("1:strGB=%p, out=%p\n", strGB, out);
 ret = iconv(cd, &strGB, &lenSrc,  &out, &lenDst);
 printf("2:strGB=%p, out=%p\n", strGB, out);
 printf("ret=%d\n", ret);
 printf("lenDst=%d\n", lenDst);
 printf("pFreeOut=%s\n", pFreeOut);
 iconv_close(cd);
 free(pFreeOut);
}

输出结果:

lenDst=40
1:strGB=0x80487e8, out=0x9714008
2:strGB=0x80487f0, out=0x9714014
ret=0
lenDst=28
pFreeOut=我是中国


转换后“我是中国”的长度为40-28=12,和out2-out1即0x9714014-0x9714008=0xC=12相符!



“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

qiek

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值