iocnv Linux字符编码转换函数 坑

来源:互联网 发布:js给input text赋值 编辑:程序博客网 时间:2024/06/05 04:51
最近写项目的时候,需要进行编码格式的转换(GB2312转换为utf-8),于是使用到了 iconv这个函数,是一个 Linux下的转码库函数。
这个函数的参数列表是这样的:
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
第二个和第四个参数都是二级指针。
因为程序需要经常的转换字符编码格式,所以 outbuf这里我选择了提前申请一段内存,而不是每次使用 都申请释放内存。

于是我就这么使用了(m_pEncodingConvertBuf是我提前申请的内存):

char **ppIn = &pInBuf;char **ppOut = &m_pEncodingConvertBuf;memset(m_pEncodingConvertBuf, 0, m_nEncodingConvertBufSize); if (iconv(m_EncodingConvert, ppIn, &nInLen, ppOut, &m_nEncodingConvertBufSize) == (unsigned int)-1){    return false;}

于是坑就出现了,无论如何转换,转换之后的 m_pEncodingConvertBuf指针里都是NULL字符,什么结果都没有,于是我各种检测参数传入的是否正确。
最后百度发现,iconv这个函数会对传入的二级指针进行修改。。。
所以,我这传入提前申请的内存 m_pEncodingConvertBuf进去,结果地址被修改了,导致 后面使用的时候结果不正确(当然,用地址被改之后的 m_pEncodingConverBuf - 地址增加数量,是可以正常打印转换后的字符的)。

应该是这么用:
bool ConvertEncoding(char *pInBuf, size_t nInLen){    char **ppIn = &pInBuf;    char *pBufTmp = m_pEncodingConvertBuf;    char **ppOut = &pBufTmp;    //需要使用临时变量 iconv会改变参数的值    size_t nEncodingConvertBufSize = m_nEncodingConvertBufSize;    memset(m_pEncodingConvertBuf, 0, m_nEncodingConvertBufSize);     //iconv会修改 ppOut指针,这里传入 pBufTmp的地址,否则 m_pEncodingConverBuf地址会被修改    if (iconv(m_EncodingConvert, ppIn, &nInLen, ppOut, &nEncodingConvertBufSize) == (unsigned int)-1)    {        printf("ConvertEncoding Failed, In:%s Out:%s\n", pInBuf, m_pEncodingConvertBuf);        return false;    }     return true;}
上面这个函数会也会修改其他参数的值,所以,一定要传入 临时的变量,这样,既不影响函数 iconv的使用,也不会影响我们 真正数据(因为传入的都是副本,随便更改,外界的原数据不会被修改)的正确性。


0 0
原创粉丝点击