乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      iconv字符編碼轉(zhuǎn)換全攻略

       quasiceo 2013-02-20

      iconv字符編碼轉(zhuǎn)換全攻略

      分類: 開(kāi)源庫(kù)介紹 1169人閱讀 評(píng)論(0) 收藏 舉報(bào)

              iconv(http://www./software/libiconv/)是一個(gè)開(kāi)源的字符編碼轉(zhuǎn)換庫(kù),可以“方便”的完成幾乎所有的編碼轉(zhuǎn)換工作。說(shuō)簡(jiǎn)單是因?yàn)椋S玫慕涌诰腿齻€(gè),iconv_open  iconv   iconv_close,但是即便是只有三個(gè)接口,要想使用正確也不容易。這里把一些基本概念和使用細(xì)節(jié)記錄下來(lái),希望能成為一篇最實(shí)用的入門(mén)教程。
       
      一、字符編碼基本概念
            更詳細(xì)的內(nèi)容可以參考百度百科(http://baike.baidu.com/view/1204863.htm),或是自行g(shù)oogle。這里會(huì)記錄最核心的幾個(gè)概念。
            1、ASCII編碼,就是英文顯示文字所需要的256個(gè)字符(比如,英文字母、數(shù)字、標(biāo)點(diǎn)符號(hào)等等)

            2、ANSI編碼,像中文,肯定不能只用256個(gè)字符就代表所有漢字。因此對(duì)ASCII碼表進(jìn)行了擴(kuò)展,使用兩個(gè)(或多個(gè))字節(jié),代表一個(gè)漢字。類似的,不同的國(guó)家和地區(qū)制定了不同的標(biāo)準(zhǔn),這些使用 2 個(gè)字節(jié)來(lái)代表一個(gè)字符的各種延伸編碼方式,稱為 ANSI 編碼。也就是說(shuō),ANSI是一種對(duì)ASCII碼表進(jìn)行擴(kuò)展的泛稱,不同語(yǔ)言操作系統(tǒng),其代表的編碼方式不一樣。比如中文操作系統(tǒng),ANSI編碼就代指GB2312;日文操作系統(tǒng)ANSI編碼就代指JIS。
            
            3、Unicode編碼,Unicode是一個(gè)超大的集合,也是一個(gè)統(tǒng)一的標(biāo)準(zhǔn),可以容納世界上的所有語(yǔ)言符號(hào)。每個(gè)符號(hào)的編碼都不一樣,比如,U+0639表示阿拉伯字母Ain,U+0041表示英語(yǔ)的大寫(xiě)字母A,“漢”這個(gè)字的Unicode編碼是U+6C49。

            4、代碼頁(yè)(codepage),Unicode是一個(gè)世界統(tǒng)一的標(biāo)準(zhǔn),也就是說(shuō),如果一個(gè)文本是用Unicode方式編碼的,那么它可以同時(shí)顯示中文、日文、阿拉伯文等等,并且是在任何系統(tǒng)上都可以正常顯示的。但是由于ANSI編碼之間互不兼容,因此就需要有一個(gè)標(biāo)識(shí)來(lái)表明不同的ANSI編碼到Unicode之間的映射關(guān)系(也就是不同編碼之間的映射關(guān)系),這個(gè)就是代碼頁(yè)。比如簡(jiǎn)體中文的代碼頁(yè)是CP_936(中文系統(tǒng)默認(rèn)的代碼頁(yè)),這個(gè)也就是windows API中MultiByteToWideChar第一個(gè)參數(shù)所代表的含義。如果不標(biāo)明代碼頁(yè),系統(tǒng)是不知道如何進(jìn)行編碼轉(zhuǎn)換的。

          5、SBCS(單字節(jié)字符集),MBCS(多字節(jié)字符集),DBCS(寬字節(jié)字符集),分別對(duì)應(yīng)上面提到的ASCII編碼、ANSI編碼、Unicode編碼。

          6、中文常見(jiàn)編碼:GB2312(CP_20936)->GBK(CP_936)->GB18030(CP_54936),三種編碼方式向下兼容,也就是說(shuō)GB18030包含GB2312的所有字符。GB18030在2000年取代GBK成為正式國(guó)家標(biāo)準(zhǔn)。

          7、UCS(Unicode Character Set):UCS-2規(guī)定了2個(gè)字節(jié)代表一個(gè)文字,還有UCS-4規(guī)定了4個(gè)字節(jié)代表一個(gè)文字。我們工作中幾乎總是在和UCS-2打交道。

         8、UTF(UCS Transformation Format):UCS只是規(guī)定的如何編碼,但是沒(méi)有規(guī)定如何傳輸、保存這個(gè)編碼。UTF則規(guī)定了由幾個(gè)字節(jié)保存這個(gè)編碼。UTF-7,UTF-8,UTF-16都是比較常見(jiàn)的編碼方式。UTF-8編碼與Unicode編碼并不相同,但是它們之間可以通過(guò)計(jì)算進(jìn)行轉(zhuǎn)換,而不像ANSI和Unicode之間必須通過(guò)一個(gè)映射表來(lái)人為規(guī)定其對(duì)應(yīng)關(guān)系。UTF-16完全對(duì)應(yīng)于UCS-2,并可通過(guò)計(jì)算代表一部分UCS-4文字。還有UTF-32則是完全對(duì)應(yīng)于UCS-4,不過(guò)很不常見(jiàn)就是了。

         9、UTF-8是與ASCII碼兼容的,英文字母1個(gè)字節(jié),漢字通常是3個(gè)字節(jié);UTF-16的所有字符都是用2個(gè)字節(jié)進(jìn)行保存,其編碼與Unicode是等價(jià)的。UTF-16又分為UTF-16LE(little endian)和UTF-16BE(big endian),比如一個(gè)字母'a',如果按utf-8來(lái)存,就是0x61;如果按utf-16le來(lái)存就是0x61 0x00(低有效位在前);如果按utf-16be來(lái)存就是0x00 0x61(高有效位在前)。這個(gè)也就是我們用記事本另存文件的時(shí)候可以選擇的幾個(gè)編碼方式的含義。

         10、BOM(byte order mark),上面提到的utf-8 utf-16le utf16-be都是unicode編碼,但是系統(tǒng)依然無(wú)法正確解析一個(gè)文本文件,即便已經(jīng)知道它是unicode編碼。所以就有了這樣的規(guī)定:在文本文件的最開(kāi)頭插入幾個(gè)字節(jié)的標(biāo)識(shí),來(lái)說(shuō)明編碼方式。utf-8的BOM是0xef 0xbb 0xbf,utf-16le的BOM是0xff 0xfe,utf16-be的BOM是0xfe 0xff。事實(shí)上BOM并不是必須的,它僅僅是幫助程序自動(dòng)判斷編碼方式使用的,如果我們手動(dòng)選擇編碼方式(像ANSI一樣),即便沒(méi)有BOM,也是可以正常顯示的。反過(guò)來(lái)說(shuō),程序讀文本文件的時(shí)候要先讀文本開(kāi)始的三個(gè)字節(jié)判斷下編碼方式。


      二、iconv支持的編碼格式:

      European languages
      ASCII, 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,1131}, Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, Mac{Cyrillic,Ukraine,Greek,Turkish}, Macintosh
      Semitic languages
      ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic}
      Japanese
      EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1
      Chinese
      EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, BIG5-HKSCS:2004, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, ISO-2022-CN-EXT
      Korean
      EUC-KR, CP949, ISO-2022-KR, JOHAB
      Armenian
      ARMSCII-8
      Georgian
      Georgian-Academy, Georgian-PS
      Tajik
      KOI8-T
      Kazakh
      PT154, RK1048
      Thai
      ISO-8859-11, TIS-620, CP874, MacThai
      Laotian
      MuleLao-1, CP1133
      Vietnamese
      VISCII, TCVN, CP1258
      Platform specifics
      HP-ROMAN8, NEXTSTEP
      Full Unicode
      UTF-8 
      UCS-2, UCS-2BE, UCS-2LE 
      UCS-4, UCS-4BE, UCS-4LE 
      UTF-16, UTF-16BE, UTF-16LE 
      UTF-32, UTF-32BE, UTF-32LE 
      UTF-7 
      C99, JAVA
      Full Unicode, in terms of uint16_t or uint32_t (with machine dependent endianness and alignment)
      UCS-2-INTERNAL, UCS-4-INTERNAL
      Locale dependent, in terms of `char' or `wchar_t' (with machine dependent endianness and alignment, and with OS and locale dependent semantics)
      char, wchar_t 
      The empty encoding name "" is equivalent to "char": it denotes the locale dependent character encoding.
      When configured with the option --enable-extra-encodings, it also provides support for a few extra encodings:
      European languages
      CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125}
      Semitic languages
      CP864
      Japanese
      EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3
      Chinese
      BIG5-2003 (experimental)
      Turkmen
      TDS565
      Platform specifics
      ATARIST, RISCOS-LATIN1

          通過(guò)第一部分的講解,這些編碼格式應(yīng)該看著比較清晰了。比如gb2312-->unicode的轉(zhuǎn)化就是GBK(或者是gb18030  cp936,我們之前說(shuō)過(guò),大多數(shù)情況這些是等價(jià)的)到ucs-2(或者是utf-16,如果文本信息中沒(méi)有BOM就要特別指定utf-16le或是utf-16be)的轉(zhuǎn)化。這些就是我們將要用到的編碼轉(zhuǎn)換的參數(shù)。

      三、iconv函數(shù)詳解
      1、iconv_t iconv_open (const char* tocode, const char* fromcode);

      如果轉(zhuǎn)換編碼不支持(通常是寫(xiě)錯(cuò)了),那么就返回-1,否則返回一個(gè)句柄。tocode和fromcode傳的就是上面列表中的參數(shù)。補(bǔ)充,如果在tocode后面追加"//TRANSLIT"(比如"utf-8//TRANSLIT"),那么如果一個(gè)字符無(wú)法被轉(zhuǎn)換,則會(huì)自動(dòng)尋找相似字符進(jìn)行替換。如果追加的是"//IGNORE",則會(huì)忽略無(wú)法轉(zhuǎn)換的字符。

      2、size_t iconv (iconv_t cd,
                    const char* * inbuf, size_t * inbytesleft,
                    char* * outbuf, size_t * outbytesleft);
              真正用于轉(zhuǎn)換的函數(shù),cd就是iconv_open返回的句柄,要注意,iconv會(huì)修改傳入的參數(shù),所以要保存好原始o(jì)utbuf指針。轉(zhuǎn)換完畢后inbuf會(huì)指向無(wú)法成功轉(zhuǎn)換而被截?cái)嗟牡谝粋€(gè)字符,inbutesleft顧名思義就是有多少字符尚未轉(zhuǎn)換,如果全部轉(zhuǎn)換成功當(dāng)然就是0了,outbuf指向輸出緩存的轉(zhuǎn)換后的字符的末尾,outbutesleft表明輸出緩存尚有多少自己剩余。
      這個(gè)函數(shù)有很多細(xì)節(jié)需要注意。如果inbuf中遇到非法字節(jié)序列會(huì)截?cái)?,這時(shí)inbuf就指向被截?cái)嗟牡谝粋€(gè)字節(jié)。這種情況一般出現(xiàn)在編碼指定錯(cuò)誤或者是數(shù)據(jù)源被截?cái)嗟臅r(shí)候。比如我們指定gb2312轉(zhuǎn)ut-8,但是數(shù)據(jù)源里出現(xiàn)阿拉伯字符,這個(gè)時(shí)候就會(huì)發(fā)生截?cái)唷?         如果outbuf空間不足,也會(huì)發(fā)生截?cái)?,不過(guò)這種情況相對(duì)少見(jiàn),因?yàn)槲覀兂绦蛑袝?huì)保證輸出緩存有足夠空間。
             另一種情況相對(duì)比較“正?!保褪潜晦D(zhuǎn)的字符集不包含源字符集的字符,比如utf-8到gb2312的轉(zhuǎn)換就很有可能發(fā)生這種情況。這時(shí)tocode的追加參數(shù)就起作用了,iconv會(huì)自動(dòng)進(jìn)行替換或者忽略。
             如果轉(zhuǎn)換成功(沒(méi)有發(fā)生截?cái)啵?,iconv返回的是不可逆的字符總數(shù)(也就是被替換或是忽略的字符總數(shù),如果一切正常,應(yīng)該返回0),如果轉(zhuǎn)換失敗,返回-1.


      3、int iconv_close (iconv_t cd);
      釋放句柄資源。

      四、utf-8-->gb18030轉(zhuǎn)換示例
          這個(gè)代表了ansi和utf-8或者是ansi之間互相轉(zhuǎn)換的代碼寫(xiě)法。
      1. <span style="font-size:16px;">iconv_t cd = iconv_open("gb18030//TRANSLIT""<span style="font-family: Georgia; ">utf-8</span>");  
      2. const char* inbuffer; // 輸入源,要轉(zhuǎn)換的字符串  
      3. int srcLen = strlen(inbuffer);  
      4. int outLen = 1024;  
      5. static char s_outbuffer[outLen];  
      6. memset(s_outbuffer, 0, outLen);  
      7. const char* srcStart = inbuffer;  
      8. char* tempOutBuffer = s_outbuffer;//要有這個(gè)臨時(shí)變量,否則iconv會(huì)直接改寫(xiě)s_outbuffer指針  
      9. size_t ret = iconv(<span style="font-family:Georgia;">cd</span>, (const char**)&srcStart, (size_t *)&srcLen, &tempOutBuffer, (size_t *)&outLen);  
      10. iconv_close(cd);  
      11.   
      12. </span>  

      五、unicode->gb18030轉(zhuǎn)換示例
            這個(gè)代表了寬字符和多字節(jié)之間的轉(zhuǎn)換,也就是wchar_t和char之間的轉(zhuǎn)換,也就是WideCharToMultiByte所完成的操作。

      1. FILE* fp = fopen("test-utf16be.txt""rb"); // 文件是unicode文件,這里要用"rb"來(lái)讀取,否則有些字節(jié)等同于EOF文件會(huì)被截?cái)?/span>  
      2. char srcBuffer[1024] = {0};  
      3. fread(srcBuffer, sizeof(srcBuffer) - 1, 1, fp);  
      4.   
      5. // 讀取BOM信息  
      6. // char x[2];  
      7. // fread(&x[0], 1, 1, fp);  
      8. // fread(&x[1], 1, 1, fp);  
      9.   
      10. // 帶有BOM信息,直接用"utf-16";否則應(yīng)該特別指定"utf-16le"或是"utf-16be",這個(gè)要區(qū)分清楚,否則會(huì)出現(xiàn)亂碼  
      11. iconv_t cd = iconv_open("gb18030//TRANSLIT""utf-16");  
      12. int srcLen = 1024;<span style="white-space:pre">    </span>// srcLen和outLen代表的都是字節(jié)數(shù),如果是wchar_t就是字符數(shù)*sizeof(wchar_t)  
      13. int outLen = 1024;  
      14. static char s_outbuffer[outLen];  
      15. memset(s_outbuffer, 0, outLen);  
      16. const char* srcStart = (const char*)srcBuffer;// srcBuffer同樣可以是wchar_t,這里也是這樣強(qiáng)制轉(zhuǎn)換  
      17. char* tempOutBuffer = s_outbuffer;//要有這個(gè)臨時(shí)變量,否則iconv會(huì)直接改寫(xiě)s_outbuffer指針  
      18. size_t ret = iconv(cd, (const char**)&srcStart, (size_t *)&srcLen, &tempOutBuffer, (size_t *)&outLen);  
      19. iconv_close(cd);  








        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多