iconv() 特殊字符集“◥◣★”转换问题

时间:2022-06-26 08:42:14
C语言 iconv 函数UTF-8 转换 GB2312 出现如下错误:
   iconv() Change error :: Invalid or incomplete multibyte or wide character
   经核查数据带有 ◥◣测试◢◤特殊字符的UTF-8编码转换不成功,其他无特殊字符的转换成功;
   安装字符集大小排序 GB18030 > GBK > GB2312 更换GB2312为GBK或GB18030转换不报错,但是转换特殊字符还是不成功。

在LINUX系统下,使用iconv -l |grep -i gb 查看中文字符集为:
CN-GB//
CSGB2312//
CSISO58GB1988//
EBCDIC-CP-GB//
GB//
GB2312//
GB13000//
GB18030//
GBK//
GB_1988-80//
GB_198880//
ISO646-GB//
   

15 个解决方案

#1


无人回答吗?自己顶一下!

#2


我用下面代码在VS2010上试了一下,含有特殊字符的果然不能正常转换。不过没有看到报错。

#include <iostream>
#include <iconv.h>
using namespace std;

#pragma comment(lib,"iconv.lib")
 
int code_convert(char *from_charset,char *to_charset,const char *inbuf, size_t inlen,char *outbuf, size_t outlen)
{
iconv_t cd;
const 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, pin, &inlen,pout, &outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
 
/* UTF-8 to GB2312  */
int u2g(const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
return code_convert("UTF-8","GB2312",inbuf,inlen,outbuf,outlen);
}
 
/* GB2312 to UTF-8 */
int g2u(const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
return code_convert("GB2312", "UTF-8", inbuf, inlen, outbuf, outlen);
}

int main(int argc, char* argv[])
{
char* inbuf = "测试"; // OK
//char* inbuf = "◥◣测试"; // NOT OK
char* outbuf1 = new char[100];
char* outbuf2 = new char[100];

g2u(inbuf, strlen(inbuf), outbuf1, 100);
cout << outbuf1 << endl;

u2g(outbuf1, strlen(outbuf1), outbuf2, 100);
cout << outbuf2 << endl;

delete[] outbuf1;
delete[] outbuf2;
}

#3


调试了一下,碰到特殊字符:
iconv(cd, pin, &inlen,pout, &outlen)就立即返回-1了。

#4


是不是编译器编译的时候就没把特殊字符的编码给弄对?
建议查看下特殊字符的编码是多少,然后直接在代码里写上值,再试试看

#5


嗯。。没报错应该是系统的差异问题!这个转换不成功是个问题啊,等大家回帖啊,人多力量大啊

#6


http://club.topsage.com/thread-533616-1-1.html

GB2312字符集
作用:国家简体中文字符集,兼容ASCII。
位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。

特殊字符 ◥ 的值是 25E5,不在GB2312内

#7


该回复于2011-04-18 17:23:46被版主删除

#8


http://download.csdn.net/source/971936
这里有个转换表

#9


把GB2312 换成GB18030 解码还是不成功啊 

#10


引用 6 楼 luciferisnotsatan 的回复:
http://club.topsage.com/thread-533616-1-1.html

GB2312字符集
作用:国家简体中文字符集,兼容ASCII。
位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。

特殊字符 ◥ 的值是 25E5,不……


嗯,估计就是这个原因了。

#11


应该就是六楼说的原因了。

#12


我说错了,我那个是Unicode编码值(从UTF8转到Unicode的值),不是GB2312。
不过看说明,GB2312应该不含那个特殊字符。
lz可以去看看unicode转那几种编码的转换关系,看看是不是没有对应的编码值。

#13


个人猜测
GB2312  不在编码范围内,报错。
GBK和GB18030,在编码范围内,但对应的字符不是那个特殊字符(可能那个值留着还没使用)。 

#14


 使用 GB18030 解码出来还是乱码,没办法只能些代码过滤掉 ◥◣ ◢◤ 这些特殊字符了

#15


GB2312字符集 < UTF-8 ,这样转当然有些字符转不了。

引用 3 楼 pathuang68 的回复:
调试了一下,碰到特殊字符:
iconv(cd, pin, &amp;inlen,pout, &amp;outlen)就立即返回-1了。


我会考虑在这返回-1时,把那些字符定义为 **  。。。

#1


无人回答吗?自己顶一下!

#2


我用下面代码在VS2010上试了一下,含有特殊字符的果然不能正常转换。不过没有看到报错。

#include <iostream>
#include <iconv.h>
using namespace std;

#pragma comment(lib,"iconv.lib")
 
int code_convert(char *from_charset,char *to_charset,const char *inbuf, size_t inlen,char *outbuf, size_t outlen)
{
iconv_t cd;
const 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, pin, &inlen,pout, &outlen)==-1) return -1;
iconv_close(cd);
return 0;
}
 
/* UTF-8 to GB2312  */
int u2g(const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
return code_convert("UTF-8","GB2312",inbuf,inlen,outbuf,outlen);
}
 
/* GB2312 to UTF-8 */
int g2u(const char *inbuf, size_t inlen, char *outbuf, size_t outlen)
{
return code_convert("GB2312", "UTF-8", inbuf, inlen, outbuf, outlen);
}

int main(int argc, char* argv[])
{
char* inbuf = "测试"; // OK
//char* inbuf = "◥◣测试"; // NOT OK
char* outbuf1 = new char[100];
char* outbuf2 = new char[100];

g2u(inbuf, strlen(inbuf), outbuf1, 100);
cout << outbuf1 << endl;

u2g(outbuf1, strlen(outbuf1), outbuf2, 100);
cout << outbuf2 << endl;

delete[] outbuf1;
delete[] outbuf2;
}

#3


调试了一下,碰到特殊字符:
iconv(cd, pin, &inlen,pout, &outlen)就立即返回-1了。

#4


是不是编译器编译的时候就没把特殊字符的编码给弄对?
建议查看下特殊字符的编码是多少,然后直接在代码里写上值,再试试看

#5


嗯。。没报错应该是系统的差异问题!这个转换不成功是个问题啊,等大家回帖啊,人多力量大啊

#6


http://club.topsage.com/thread-533616-1-1.html

GB2312字符集
作用:国家简体中文字符集,兼容ASCII。
位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。

特殊字符 ◥ 的值是 25E5,不在GB2312内

#7


该回复于2011-04-18 17:23:46被版主删除

#8


http://download.csdn.net/source/971936
这里有个转换表

#9


把GB2312 换成GB18030 解码还是不成功啊 

#10


引用 6 楼 luciferisnotsatan 的回复:
http://club.topsage.com/thread-533616-1-1.html

GB2312字符集
作用:国家简体中文字符集,兼容ASCII。
位数:使用2个字节表示,能表示7445个符号,包括6763个汉字,几乎覆盖所有高频率汉字。
范围:高字节从A1到F7, 低字节从A1到FE。将高字节和低字节分别加上0XA0即可得到编码。

特殊字符 ◥ 的值是 25E5,不……


嗯,估计就是这个原因了。

#11


应该就是六楼说的原因了。

#12


我说错了,我那个是Unicode编码值(从UTF8转到Unicode的值),不是GB2312。
不过看说明,GB2312应该不含那个特殊字符。
lz可以去看看unicode转那几种编码的转换关系,看看是不是没有对应的编码值。

#13


个人猜测
GB2312  不在编码范围内,报错。
GBK和GB18030,在编码范围内,但对应的字符不是那个特殊字符(可能那个值留着还没使用)。 

#14


 使用 GB18030 解码出来还是乱码,没办法只能些代码过滤掉 ◥◣ ◢◤ 这些特殊字符了

#15


GB2312字符集 < UTF-8 ,这样转当然有些字符转不了。

引用 3 楼 pathuang68 的回复:
调试了一下,碰到特殊字符:
iconv(cd, pin, &amp;inlen,pout, &amp;outlen)就立即返回-1了。


我会考虑在这返回-1时,把那些字符定义为 **  。。。