iconv 字符集转换出错

时间:2022-01-11 08:40:23
最近有个项目在用字符集转换,网上查了下iconv的用法,直接拿过来用,发现运行一直出错,代码如下:


#include <stdio.h>
#include <iostream>
#include <iconv.h>
#include <string.h>
#include <errno.h>

int code_convert(char* from_charset, char* to_charset, char* inbuf,
               int inlen, char* outbuf, int outlen)
{
    iconv_t cd;
    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,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }

    iconv_close(cd);
    return 0;   
}


char* u2g(char *inbuf)   
{
   int nOutLen = 255;
    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("UTF-8","GBK",inbuf,strlen(inbuf),szOut,nOutLen))
    {
       free(szOut);
       szOut = NULL;
    }
    return szOut;
}   


char* g2u(char *inbuf)   
{
    int nOutLen = 255;
    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("GBK","UTF-8",inbuf,strlen(inbuf),szOut,nOutLen))
    {
         printf("error no = %d;\n",errno);
       free(szOut);
       szOut = NULL;
    }

    return szOut;
}   

 

int main(int argc, char **argv)
{  
    char src[128]={0};  
    sprintf(src,"123");
    char* szOut = g2u(src);
    if( szOut ) free(szOut); 
    return 1;

}


运行结果:
errno =84 ;
error no = 84;

一直报  EILSEQ(=84)错误,实在是不知道为什么了,请高手指教!
在线等!

15 个解决方案

#1


操作系统环境是  redhat 5.5

字符集环境:
LANG=zh_CN.gb18030
LC_CTYPE="zh_CN.gb18030"
LC_NUMERIC="zh_CN.gb18030"
LC_TIME="zh_CN.gb18030"
LC_COLLATE="zh_CN.gb18030"
LC_MONETARY="zh_CN.gb18030"
LC_MESSAGES="zh_CN.gb18030"
LC_PAPER="zh_CN.gb18030"
LC_NAME="zh_CN.gb18030"
LC_ADDRESS="zh_CN.gb18030"
LC_TELEPHONE="zh_CN.gb18030"
LC_MEASUREMENT="zh_CN.gb18030"
LC_IDENTIFICATION="zh_CN.gb18030"
LC_ALL=zh_CN.gb18030

iconv 版本
iconv (GNU libc) 2.5
Copyright (C) 2006 Free Software Foundation, Inc.

编译器版本
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.

#2


错误说明是: 非法字节序列

#3


引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

#4


引用 3 楼 zw91683 的回复:
引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。

#5


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


我在2楼的回复里写明了操作系统的字符集设置,用的是gb18030啊,我把gbk改成gb18030也是一样的错误!

#6


引用 5 楼 zw91683 的回复:
Quote: 引用 4 楼 neustar1 的回复:

Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


我在2楼的回复里写明了操作系统的字符集设置,用的是gb18030啊,我把gbk改成gb18030也是一样的错误!
程序开始要调用setlocale(LC_ALL,"zh_CN.gb18030");另外源文件记住保存成anscii编码,不可以保存为utf-8编码。

#7



#include <stdio.h>
#include <iostream>
#include <locale.h>

#include "iconv.h"

#include <string.h>
#include <errno.h>

//#include <string>


int code_convert(char* from_charset, char* to_charset, char* inbuf,

               int inlen, char* outbuf, int outlen)

{

    iconv_t cd;

    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,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)

       == -1)
    {
                        printf("errno =%d ;\n",errno);
       return -1;   
     }

    iconv_close(cd);

    return 0;   

}


char* u2g(char *inbuf)   

{

    int nOutLen = 255;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("utf-8","gb18030",inbuf,strlen(inbuf),szOut,nOutLen))

    {

       free(szOut);

       szOut = NULL;

    }

    return szOut;

}   


char* g2u(char *inbuf)   
{

    int nOutLen = 255;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("gb18030","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))

    {
         printf("error no = %d;\n",errno);
       free(szOut);

       szOut = NULL;

    }

    return szOut;

}   

 

int main(int argc, char **argv)

{
   setlocale(LC_ALL,"zh_CN.gb18030") ;
    char src[128]={0};  
    
    sprintf(src,"天空");

    char* szOut = g2u(src);
    
    return 1;

}


iconv 字符集转换出错 还是不行啊

#8


引用 7 楼 zw91683 的回复:
iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?

#9


引用 8 楼 neustar1 的回复:
Quote: 引用 7 楼 zw91683 的回复:

iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?


iconv 字符集转换出错

这个对吧?

#10


引用 9 楼 zw91683 的回复:
Quote: 引用 8 楼 neustar1 的回复:

Quote: 引用 7 楼 zw91683 的回复:

iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?


iconv 字符集转换出错

这个对吧?
对的

#11


确认一下你setlocale是否成功了

#12


引用 11 楼 neustar1 的回复:
确认一下你setlocale是否成功了


printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;

返回结果
locale =zh_CN.gb18030 ;

#13


引用 12 楼 zw91683 的回复:
Quote: 引用 11 楼 neustar1 的回复:

确认一下你setlocale是否成功了


printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;

返回结果
locale =zh_CN.gb18030 ;


还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。

#14


引用 13 楼 neustar1 的回复:
还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。


iconv 字符集转换出错 拜服!!
确实是这个原因,谢谢!

#15


引用 14 楼 zw91683 的回复:
Quote: 引用 13 楼 neustar1 的回复:

还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。


iconv 字符集转换出错 拜服!!
确实是这个原因,谢谢!
不用谢了,给分吧 iconv 字符集转换出错

#1


操作系统环境是  redhat 5.5

字符集环境:
LANG=zh_CN.gb18030
LC_CTYPE="zh_CN.gb18030"
LC_NUMERIC="zh_CN.gb18030"
LC_TIME="zh_CN.gb18030"
LC_COLLATE="zh_CN.gb18030"
LC_MONETARY="zh_CN.gb18030"
LC_MESSAGES="zh_CN.gb18030"
LC_PAPER="zh_CN.gb18030"
LC_NAME="zh_CN.gb18030"
LC_ADDRESS="zh_CN.gb18030"
LC_TELEPHONE="zh_CN.gb18030"
LC_MEASUREMENT="zh_CN.gb18030"
LC_IDENTIFICATION="zh_CN.gb18030"
LC_ALL=zh_CN.gb18030

iconv 版本
iconv (GNU libc) 2.5
Copyright (C) 2006 Free Software Foundation, Inc.

编译器版本
g++ (GCC) 4.1.2 20080704 (Red Hat 4.1.2-48)
Copyright (C) 2006 Free Software Foundation, Inc.

#2


错误说明是: 非法字节序列

#3


引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

#4


引用 3 楼 zw91683 的回复:
引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。

#5


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


我在2楼的回复里写明了操作系统的字符集设置,用的是gb18030啊,我把gbk改成gb18030也是一样的错误!

#6


引用 5 楼 zw91683 的回复:
Quote: 引用 4 楼 neustar1 的回复:

Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


引用 4 楼 neustar1 的回复:
Quote: 引用 3 楼 zw91683 的回复:

引用
错误说明是: 非法字节序列


我知道啊,问题是怎么就非法字节序列了? 哪非法了?弄了半天没搞明白。

还有同样的代码在AIX环境下测试通过了, iconv 字符集转换出错
真搞不懂了

setlocale,设置好程序的本地化的字符编码类型,linux下默认是utf-8,这个与系统的本地化字符编码类型不一致。


我在2楼的回复里写明了操作系统的字符集设置,用的是gb18030啊,我把gbk改成gb18030也是一样的错误!
程序开始要调用setlocale(LC_ALL,"zh_CN.gb18030");另外源文件记住保存成anscii编码,不可以保存为utf-8编码。

#7



#include <stdio.h>
#include <iostream>
#include <locale.h>

#include "iconv.h"

#include <string.h>
#include <errno.h>

//#include <string>


int code_convert(char* from_charset, char* to_charset, char* inbuf,

               int inlen, char* outbuf, int outlen)

{

    iconv_t cd;

    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,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)

       == -1)
    {
                        printf("errno =%d ;\n",errno);
       return -1;   
     }

    iconv_close(cd);

    return 0;   

}


char* u2g(char *inbuf)   

{

    int nOutLen = 255;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("utf-8","gb18030",inbuf,strlen(inbuf),szOut,nOutLen))

    {

       free(szOut);

       szOut = NULL;

    }

    return szOut;

}   


char* g2u(char *inbuf)   
{

    int nOutLen = 255;

    char* szOut = (char*)malloc(nOutLen);

    if (-1 == code_convert("gb18030","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))

    {
         printf("error no = %d;\n",errno);
       free(szOut);

       szOut = NULL;

    }

    return szOut;

}   

 

int main(int argc, char **argv)

{
   setlocale(LC_ALL,"zh_CN.gb18030") ;
    char src[128]={0};  
    
    sprintf(src,"天空");

    char* szOut = g2u(src);
    
    return 1;

}


iconv 字符集转换出错 还是不行啊

#8


引用 7 楼 zw91683 的回复:
iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?

#9


引用 8 楼 neustar1 的回复:
Quote: 引用 7 楼 zw91683 的回复:

iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?


iconv 字符集转换出错

这个对吧?

#10


引用 9 楼 zw91683 的回复:
Quote: 引用 8 楼 neustar1 的回复:

Quote: 引用 7 楼 zw91683 的回复:

iconv 字符集转换出错 还是不行啊

linux下,源文件默认保存为utf-8格式,你一定要改成多字符编码格式才行。你改了源文件编码?


iconv 字符集转换出错

这个对吧?
对的

#11


确认一下你setlocale是否成功了

#12


引用 11 楼 neustar1 的回复:
确认一下你setlocale是否成功了


printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;

返回结果
locale =zh_CN.gb18030 ;

#13


引用 12 楼 zw91683 的回复:
Quote: 引用 11 楼 neustar1 的回复:

确认一下你setlocale是否成功了


printf("locale =%s ;\n",setlocale(LC_ALL,"zh_CN.gb18030")) ;

返回结果
locale =zh_CN.gb18030 ;


还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。

#14


引用 13 楼 neustar1 的回复:
还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。


iconv 字符集转换出错 拜服!!
确实是这个原因,谢谢!

#15


引用 14 楼 zw91683 的回复:
Quote: 引用 13 楼 neustar1 的回复:

还有一个原因就是
 if(iconv(cd,(char**)(const char**)pin,(size_t *)(unsigned int *)&inlen,pout,(size_t *)(unsigned int*)&outlen)== -1 )
    {
        printf("errno =%d ;\n",errno);
       return -1;   
     }
你的系统是64位的,size_t与 unsigned int大小不一样,你把这个变量改一下看看。


iconv 字符集转换出错 拜服!!
确实是这个原因,谢谢!
不用谢了,给分吧 iconv 字符集转换出错