libiconv
-
libiconv
本词条缺少名片图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!
由于历史原因,国际化的文字常常由于语言或者国家的原因使用不同的编码。
- 中文名
- libiconv
- 默认编码方式
- 就是Unicode
- 包 含
- 了所有这些编码的字符集
- 解 决
- 这种混乱
目录
libiconv历史简介
随着互联网时代的到来,通过互联网进行文字交流也逐渐增多:浏览外国的网站,这个时候字符编码的转换变得尤为重要。这带来了一个问题,就是许多字符在某一种编码方式中没有。为了解决这种混乱,Unicode的编码方式被建立。Unicode是一种超级编码包含了所有这些编码的字符集,因此一些新的文本格式像XML的默认编码方式就是Unicode.
但是很多老式的计算机还在使用当地的传统的字符编码方式。而一些程序,例如邮件程序和浏览器必须能在这些不同的用户编码之间作转换。其他的一些程序则内置支持Unicode,以顺利支持国际化的处理,但是仍然有在Unicode和其他的传统编码之间转换的需求。GNU的libiconv就是为这两种应用设计的编码转换库。
libiconv编码简介
包括的编码有:
| 欧洲语系 |
ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16},
CP{1250,1251,1252,1253,1254,1257},
CP{850,866},
Mac{Roman,CentralEurope,Iceland,Croatian,Romania},
Mac{Cyrillic,Ukraine,Greek,Turkish},
Macintosh
|
| 犹太语系 | ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic} |
| 日文 | EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1 |
| 中文 | EUC-CN, HZ, GBK, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, ISO-2022-CN, ISO-2022-CN-EXT |
| 朝鲜文 | EUC-KR, CP949, ISO-2022-KR, JOHAB |
| 亚美尼亚语 | ARMSCII-8 |
| 格鲁尼亚语 | Georgian-Academy, Georgian-PS |
| 塔吉克语 | KOI8-T |
| 泰国语 | TIS-620, CP874, MacThai |
| 老挝语 | MuleLao-1, CP1133 |
| 越南语 | VISCII, TCVN, CP1258 |
| 特殊平台 | HP-ROMAN8, NEXTSTEP |
| 全部Unicode |
UTF-8, UTF-7
UCS-2, UCS-2BE, UCS-2LE, UCS-4, UCS-4BE, UCS-4LE
UTF-16, UTF-16BE, UTF-16LE, UTF-32, UTF-32BE, UTF-32LE
C99, JAVA
|
全部Unicode,在uint16_t或uint32_t方面(使用机器相关的字节序和对齐方式):
UCS-2-INTERNAL, UCS-4-INTERNAL
本地依赖,在’char’或’wchar_t’方面(使用机器相关的字节序和对齐方式,以及系统和区域相关的语义):
char, wchar_t
空的编码名””等同于”char”,它表示与区域相关的字符编码
当使用了–enable-extra-encodings设置选项,将额外提供对少量编码的支持:
UCS-2-INTERNAL, UCS-4-INTERNAL
本地依赖,在’char’或’wchar_t’方面(使用机器相关的字节序和对齐方式,以及系统和区域相关的语义):
char, wchar_t
空的编码名””等同于”char”,它表示与区域相关的字符编码
当使用了–enable-extra-encodings设置选项,将额外提供对少量编码的支持:
|
欧洲语系
|
CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125}
|
|
犹太语系
|
CP864
|
|
日语
|
EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3
|
|
TDS565
|
|
|
特殊平台
|
RISCOS-LATIN1
|
通过将Unicode作为 中间编码,所有编码之间都可以相互转换。
并且也在直译上提供了有限的支持。就是说,当一个字符在目标的编码里没有的对应字符的时候,转换程序会自动从一个或多个看起来相似的字符中选择一个。目标编码名前面加上“//TRANSLIT”即可使用直译功能。
libiconv在系统缺少多种多样的字符编码支持时,提供这样方面的支持,
并且也在直译上提供了有限的支持。就是说,当一个字符在目标的编码里没有的对应字符的时候,转换程序会自动从一个或多个看起来相似的字符中选择一个。目标编码名前面加上“//TRANSLIT”即可使用直译功能。
libiconv在系统缺少多种多样的字符编码支持时,提供这样方面的支持,
libiconv使用举例
使用步骤
(1)打开:iconv_t converter = iconv_open(“gbk”,”utf-8″);
(2)转换:size_t rc = iconv(converter, input, insize, output, outsize);
(3)关闭:iconv_close(converter);
(2)转换:size_t rc = iconv(converter, input, insize, output, outsize);
(3)关闭:iconv_close(converter);
函数参数:
(iconv_t cd, const char* * inbuf, size_t * inbytesleft, char* * outbuf, size_t * outbytesleft);
需要注意的是iconv 函数会修改指针*inbuf 和指针*outbuf的值(刚开始不知道,老是内存泄漏)(*inbytesleft,*outbytesleft也会被修改)。因此需要保存原输入、输出内存分配的地址值。
需要注意的是iconv 函数会修改指针*inbuf 和指针*outbuf的值(刚开始不知道,老是内存泄漏)(*inbytesleft,*outbytesleft也会被修改)。因此需要保存原输入、输出内存分配的地址值。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
//要转换至的编码应与编译器使用的默认编码不同,相同的话将转换失败//比如VC6.0中文默认使用<a target="_blank" href="/item/UTF-8/481798" data-lemmaid="481798">UTF-8</a>进行编码,iconv_open("gbk","UTF-8");将失败#include <iostream>#include <iconv.h>using namespace std;#pragma comment(lib,"iconv.lib")int main(){ iconv_t conveter = iconv_open("gbk","UTF-8"); if(conveter== iconv_t(-1)){ cout<<"encode convert not supported!"<<<a target="_blank" href="/item/endl/6256824" data-lemmaid="6256824">endl</a>; if(<a target="_blank" href="/item/errno/11040395" data-lemmaid="11040395">errno</a>==EINVAL)cout<<"einval"<<endl; return -1; } else{ cout<<"ok!"<<<a target="_blank" href="/item/endl/6256824" data-lemmaid="6256824">endl</a>; } //待转换的字符串 size_t insize; const char *input = "hello是";//汉字随便加//应是const char *而不是char * //char *input_old = <a target="_blank" href="/item/input/9795343" data-lemmaid="9795343">input</a>; //记录待转换字符串的地址 //input_old is unused variable. insize=<a target="_blank" href="/item/strlen/3103907" data-lemmaid="3103907">strlen</a>(input); cout<<"input is: "<<input<<<a target="_blank" href="/item/endl/6256824" data-lemmaid="6256824">endl</a>; //存储转换结果的字符串 size_t outsize = insize * 3+1; char *output = new char[outsize]; char *output_old = output;//记录转换后的字符串的地址 <a target="_blank" href="/item/memset/4747579" data-lemmaid="4747579">memset</a>(output,0,outsize); //转换 //size_t rc = <a target="_blank" href="/item/iconv/524310" data-lemmaid="524310">iconv</a>(conveter,(const char **)&<a target="_blank" href="/item/input/9795343" data-lemmaid="9795343">input</a>,&insize,&output_old,&outsize); //参数要求char **不是const char **。可能存在版本问题。 size_t ret = <a target="_blank" href="/item/iconv/524310" data-lemmaid="524310">iconv</a>(converter,(char**)&input,&insize,&output_old,&outsize); //if(rc==-1){ //size_t 是<a target="_blank" href="/item/unsigned/8604216" data-lemmaid="8604216">unsigned</a>类型 if(ret==(<a target="_blank" href="/item/size_t/8101179" data-lemmaid="8101179">size_t</a>)-1) cout<<"converting failed"<<<a target="_blank" href="/item/endl/6256824" data-lemmaid="6256824">endl</a>; return -1; } //输出转换后的字符串 //cout<<"outputis: "<<output_old; //output_old已经被改变了。应使用output来输出结果。 cout<<"output is : "<<coutput; cout<<" outsize="<<outsize<<<a target="_blank" href="/item/endl/6256824" data-lemmaid="6256824">endl</a>; //delete[] input_old;//<a target="_blank" href="/item/%E5%86%85%E5%AD%98%E9%87%8A%E6%94%BE/6710865" data-lemmaid="6710865">内存释放</a>,不需要释放它,<a target="_blank" href="/item/%E5%B8%B8%E9%87%8F/9513687" data-lemmaid="9513687">常量</a>字符串 //delete[] output_old; //内存释放 //应释放的位置不是output_old,理由同上。 delete[] output; iconv_close(conveter);} |
