iconv函数详细解释

基础知识 专栏收录该内容
37 篇文章 0 订阅

最近在使用iconv函数,感觉iconv的函数参数很奇怪。仔细研究了一下,发现iconv实际上一个返回多个值的函数。此函数利用函数参数,同时返回了好几个值,每个函数参数既是入参,也是出参。详细解释如下:


iconv的原型如下:
	size_t iconv(iconv_t cd,char **inbuf,size_t *inbytesleft,char **outbuf,size_t *outbytesleft);


函数参数比较奇怪的地方有:
 1.inbuf 为什么是二级指针,而不是一级指针。
 2.inbytesleft为什么是指针,而不是普通变量。
 3.outbuf 为什么是二级指针,而不是一级指针。
 4.outbytesleft 为什么是指针,而不是普通变量
 

原来,函数执行后,由于各种原因(输出缓冲区太小,输入字符串不是一种编码,而是含有多种编码),可能只转换了部分编码。这时返回值为-1,这时会改变后四个参数的值。另外,即使全部转换成功,这四个参数的值也要发生变化。


作为入参
第一个参数cd是转换句柄。
第二个参数inbuf是输入字符串的地址的地址。
第三个参数inbytesleft是输入字符串的长度。
第四个参数outbuf是输出缓冲区的首地址
第五个参数outbytesLeft 是输出缓冲区的长度。


作为出参
第一个参数cd是转换句柄。
第二个参数inbuf指向剩余字符串的地址
第三个参数inbytesleft是剩余字符串的长度。
第四个参数outbuf是输出缓冲区剩余空间的首地址
第五个参数outbytesLeft 是输出缓冲区剩余空间的长度。

这下,同学们应该明白为什么后四个参数,为什么要多取一级地址了吧。

下面是几个例子:

int UTF8ToGBK(char* input, size_t& charInPutLen, char* output, size_t& charOutPutLen)
{
    
    int ret =0;
    iconv_t cd;
    cd = iconv_open("GBK","utf-8");
    ret = iconv(cd, &input, &charInPutLen, &output, &charOutPutLen);
    iconv_close(cd);
    return ret;
}

int UTF8ToGBK(const string& input, string& output)
{
	int ret =0;
	size_t charInPutLen = input.length();
	if( charInPutLen == 0)
		return 0;
	char *pSource =(char *)input.c_str();
    size_t charOutPutLen = 2*charInPutLen;
	char *pTemp = new char[charOutPutLen];
	memset(pTemp,0,2*charInPutLen);
	
	iconv_t cd;
    char *pSource =(char *)input.c_str();
    char *pOut = pTemp ;
    cd = iconv_open("utf-8", "GBK");
    ret = iconv(cd, &pSource, &charInPutLen, &pTemp, &charOutPutLen);
    iconv_close(cd);
	output = pOut;
	delete []pOut;//注意这里,不能使用delete []pTemp, iconv函数会改变指针pTemp的值
	return ret;
}

int  GBKToUTF8(char* input, size_t charInPutLen, char* output, size_t &charOutPutLen)
{
	int ret = 0;
    iconv_t cd;
    cd = iconv_open("utf-8", "GBK");
    ret = iconv(cd, &input, &charInPutLen, &output, &charOutPutLen);
    iconv_close(cd);
    return ret;
}


int  GBKToUTF8(const string& input, string& output)
{
	int ret = 0;
	size_t charInPutLen = input.length();
	if( charInPutLen == 0)
		return 0;
	
	size_t charOutPutLen = 2*charInPutLen+1;
	char *pTemp = new char[charOutPutLen];
	memset(pTemp,0,charOutPutLen);
    iconv_t cd;
    char *pSource =(char *)input.c_str();
    char *pOut = pTemp;
    cd = iconv_open("utf-8", "GBK");
    ret = iconv(cd, &pSource, &charInPutLen, &pTemp, &charOutPutLen);
    iconv_close(cd);
	output= pOut;
	delete []pOut; //注意这里,不能使用delete []pTemp, iconv函数会改变指针pTemp的值
    return ret;
}


  • 3
    点赞
  • 6
    评论
  • 16
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

聪明的狐狸

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

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

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

打赏作者

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

抵扣说明:

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

余额充值