複製鏈接
請複製以下鏈接發送給好友

libiconv

鎖定
由於歷史原因,國際化的文字常常由於語言或者國家的原因使用不同的編碼。
中文名
libiconv
默認編碼方式
就是Unicode
包    含
了所有這些編碼的字符集
解    決
這種混亂

libiconv歷史簡介

隨着互聯網時代的到來,通過互聯網進行文字交流也逐漸增多:瀏覽外國的網站,這個時候字符編碼的轉換變得尤為重要。這帶來了一個問題,就是許多字符在某一種編碼方式中沒有。為了解決這種混亂,Unicode的編碼方式被建立。Unicode是一種超級編碼包含了所有這些編碼的字符集,因此一些新的文本格式像XML的默認編碼方式就是Unicode.
但是很多老式的計算機還在使用當地的傳統的字符編碼方式。而一些程序,例如郵件程序和瀏覽器必須能在這些不同的用户編碼之間作轉換。其他的一些程序則內置支持Unicode,以順利支持國際化的處理,但是仍然有在Unicode和其他的傳統編碼之間轉換的需求。GNU的libiconv就是為這兩種應用設計的編碼轉換庫。

libiconv編碼簡介

libiconv庫 [1]  為需要做轉換的應用提供了一個iconv的函數,以實現一個字符編碼到另一個字符編碼的轉換。
包括的編碼有:
歐洲語系
ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16},
KOI8-R, KOI8-U, KOI8-RU,
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設置選項,將額外提供對少量編碼的支持:
歐洲語系
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在系統缺少多種多樣的字符編碼支持時,提供這樣方面的支持,

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);

libiconv函數參數

(iconv_t cd, const char* * inbuf, size_t* inbytesleft, char* * outbuf, size_t * outbytesleft);
需要注意的是iconv 函數會修改指針*inbuf 和指針*outbuf的值(剛開始不知道,老是內存泄漏)(*inbytesleft*outbytesleft也會被修改)。因此需要保存原輸入、輸出內存分配的地址值。
//要轉換至的編碼應與編譯器使用的默認編碼不同,相同的話將轉換失敗
//比如VC6.0中文默認使用
UTF-8進行編碼,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!"<<
endl;
        if(
errno==EINVAL)cout<<"einval"<<endl;    
        return -1;    
    }
    else{
        cout<<"ok!"<<
endl;    
    }
    
    //待轉換的字符串
    size_t insize;
    const char *input = "hello是";//漢字隨便加//應是const char *而不是char *
    //char *input_old = 
input; //記錄待轉換字符串的地址
    //input_old is unused variable.
    insize=
strlen(input);
    cout<<"input is: "<<input<<
endl;
    
    //存儲轉換結果的字符串
    size_t outsize = insize * 3+1;
    char *output = new char[outsize];
    char *output_old = output;//記錄轉換後的字符串的地址
    
memset(output,0,outsize);         
    
    //轉換
    //size_t rc = 
iconv(conveter,(const char **)&
input,&insize,&output_old,&outsize);
    //參數要求char **不是const char **。可能存在版本問題。
    size_t ret = 
iconv(converter,(char**)&input,&insize,&output_old,&outsize);
    //if(rc==-1){
    //size_t 是
unsigned類型
    if(ret==(
size_t)-1)
        cout<<"converting failed"<<
endl;
        return -1;
    }
    
    //輸出轉換後的字符串
    //cout<<"outputis: "<<output_old;
    //output_old已經被改變了。應使用output來輸出結果。
    cout<<"output is : "<<coutput;
    cout<<"  outsize="<<outsize<<
endl;
    
    //delete[] input_old;//
內存釋放,不需要釋放它,
常量字符串
    //delete[] output_old; //內存釋放
    //應釋放的位置不是output_old,理由同上。
    delete[] output;
    iconv_close(conveter);
}

參考資料