当前位置: 技术问答>linux和unix
请教iconv函数的用法?
来源: 互联网 发布时间:2015-07-14
本文导语: 我要写一个函数,用iconv把unicode串转成gb2312,函数是这样的, // UCS2解码 // 输入: pSrc - 源编码串指针 //nSrcLength - 源编码串长度 // 输出: pDst - 目标字符串指针 // 返回: 目标字符串长度 int gsmDecodeUcs2(const unsigned...
我要写一个函数,用iconv把unicode串转成gb2312,函数是这样的,
// UCS2解码
// 输入: pSrc - 源编码串指针
//nSrcLength - 源编码串长度
// 输出: pDst - 目标字符串指针
// 返回: 目标字符串长度
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
int nDstLength;
int i;
int len;
iconv_t cd;
char wchar[256]; // UNICODE串缓冲区
char tmp;
char* pin = wchar;
char* pout = pDst;
len = nSrcLength;
// 高低字节对调,拼成UNICODE
for(i=0; i字符串
cd = iconv_open("unicode","gb2312");
if (cd == (iconv)-1)
return -1;
iconv(cd,(const char **)&pin,&len,&pout,&nDstLength);
// 输出字符串加个结束符
pDst[nDstLength] = '';
// 返回目标字符串长度
return nDstLength;
}
用GDB调试,假如buf={0x4f,0x60,0x59,0x7d,....},而nSrcLength=4时,wchar={0x60,0x4f,0x7d,0x59,...},但是执行iconv语句之后,nDstLength=839166312.这样就造成越界了,应该返回4啊。
// UCS2解码
// 输入: pSrc - 源编码串指针
//nSrcLength - 源编码串长度
// 输出: pDst - 目标字符串指针
// 返回: 目标字符串长度
int gsmDecodeUcs2(const unsigned char* pSrc, char* pDst, int nSrcLength)
{
int nDstLength;
int i;
int len;
iconv_t cd;
char wchar[256]; // UNICODE串缓冲区
char tmp;
char* pin = wchar;
char* pout = pDst;
len = nSrcLength;
// 高低字节对调,拼成UNICODE
for(i=0; i字符串
cd = iconv_open("unicode","gb2312");
if (cd == (iconv)-1)
return -1;
iconv(cd,(const char **)&pin,&len,&pout,&nDstLength);
// 输出字符串加个结束符
pDst[nDstLength] = '';
// 返回目标字符串长度
return nDstLength;
}
用GDB调试,假如buf={0x4f,0x60,0x59,0x7d,....},而nSrcLength=4时,wchar={0x60,0x4f,0x7d,0x59,...},但是执行iconv语句之后,nDstLength=839166312.这样就造成越界了,应该返回4啊。
|
nDstLength是一个input参数,不是一个output参数,
你的程序nDstLength没有赋值,会在pDst[nDstLength] = '';处crash.
man iconv
The main case is when inbuf is not NULL and *inbuf is not NULL. In this case, the
iconv function converts the multibyte sequence starting at *inbuf to a multibyte
sequence starting at *outbuf. At most *inbytesleft bytes, starting at *inbuf, will
be read. At most *outbytesleft bytes, starting at *outbuf, will be written.
你的程序nDstLength没有赋值,会在pDst[nDstLength] = '';处crash.
man iconv
The main case is when inbuf is not NULL and *inbuf is not NULL. In this case, the
iconv function converts the multibyte sequence starting at *inbuf to a multibyte
sequence starting at *outbuf. At most *inbytesleft bytes, starting at *inbuf, will
be read. At most *outbytesleft bytes, starting at *outbuf, will be written.
|
int u2g(char *inbuf,int inlen,char *outbuf,int outlen)
{
return CodeConvert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
int CodeConvert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0)
return -1;
memset(outbuf,0,outlen);
if (iconv(cd, (const char **)pin, (size_t*)&inlen, pout, (size_t*)&outlen)==-1)
return -1;
iconv_close(cd);
return 0;
}
{
return CodeConvert("utf-8","gb2312",inbuf,inlen,outbuf,outlen);
}
int CodeConvert(char *from_charset,char *to_charset,char *inbuf,int inlen,char *outbuf,int outlen)
{
iconv_t cd;
int rc;
char **pin = &inbuf;
char **pout = &outbuf;
cd = iconv_open(to_charset,from_charset);
if (cd==0)
return -1;
memset(outbuf,0,outlen);
if (iconv(cd, (const char **)pin, (size_t*)&inlen, pout, (size_t*)&outlen)==-1)
return -1;
iconv_close(cd);
return 0;
}