使用iconv進行內碼轉換(Big5->GB2312)

概述
iconv是一個通過unicode作爲中間碼實現各種內碼間相互轉換的庫,它基本上囊括了世界上所有編碼方式,例如,ASCII、GB2312、 GBK、 GB18030、BIG5、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等等等,除此之外,還包括泰語、日語、韓語、西歐等 國家語言的編碼。下面我們演示如何使用iconv實現Big5到GB2312的轉換,當然只要簡單修改一下便可實現iconv支持任何編碼間的轉換。

下載
libiconv是linux版本的iconv,可在 http://www.gnu.org/software/libiconv/ 下載
iconv的win32版本可以在 http://gnuwin32.sourceforge.net/packages/libiconv.htm 下載

SVN源碼
另外,還有一些演示代碼,需要的可以到我的SVN下載
http://xcyber.googlecode.com/svn/trunk/Convert/

演示代碼
  1. /****************************************************************************
  2.  *  Big5ToGB2312 - Convert Big5 encoding file to GB2312 encoding file
  3.  *  File:
  4.  *    Big5ToGb2312.c
  5.  *  Description:
  6.  *    Convert Big5 encoding file to GB2312 encoding file using iconv library
  7.  *  Author:
  8.  *    XCyber   email:[email protected]
  9.  *  Date:
  10.  *    August 7, 2008
  11.  *  Other:
  12.  *    visit http://www.gnu.org/software/libiconv/ for more help of iconv
  13.  ***************************************************************************/
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <tchar.h>
  17. #include <locale.h>
  18. #include "../iconv-1.9.2.win32/include/iconv.h"
  19. //#pragma comment(lib, "../iconv-1.9.2.win32/lib/iconv.lib")  // using iconv dynamic-link lib, iconv.dll
  20. #pragma comment(lib, "../iconv-1.9.2.win32/lib/iconv_a.lib")  // using iconv static lib 
  21. #define BUFFER_SIZE 1024   //BUFFER_SIZE must >= 2
  22. void usage()
  23. {
  24.     printf("/nBig5ToGB2312 - Convert Big5 encoding file to GB2312 encoding file/n");
  25.     printf("[email protected] on August 7, 2008/n");
  26.     printf("  Usage:/n");
  27.     printf("      Big5ToGB2312 [Big5 file(in)]  [GB2312 file(out)]/n/n");
  28. }
  29. int main(int argc, char* argv[])
  30. {
  31.     FILE * pSrcFile = NULL;
  32.     FILE * pDstFile = NULL;
  33.     char szSrcBuf[BUFFER_SIZE];
  34.     char szDstBuf[BUFFER_SIZE];
  35.     size_t nSrc  = 0;
  36.     size_t nDst  = 0;
  37.     size_t nRead = 0;
  38.     size_t nRet  = 0;
  39.     char *pSrcBuf = szSrcBuf;
  40.     char *pDstBuf = szDstBuf;
  41.     iconv_t icv;
  42.     int argument = 1;
  43.     //check input arguments
  44.     if(argc != 3)
  45.     {
  46.         usage();
  47.         return -1;
  48.     }
  49.     pSrcFile = fopen(argv[1],"r");
  50.     if(pSrcFile == NULL)
  51.     {
  52.         printf("can't open source file!/n");
  53.         return -1;
  54.     }
  55.     pDstFile = fopen(argv[2],"w");
  56.     if(pSrcFile == NULL)
  57.     {
  58.         printf("can't open destination file!/n");
  59.         return -1;
  60.     }
  61.     //initialize iconv routine, perform conversion from BIG5 to GB2312
  62.     //TODO: if you want to perfom other type of coversion, e.g. GB2312->BIG5, GB2312->UTF-8 ...
  63.     //just change following two paremeters of iconv_open()
  64.     icv = iconv_open("GB2312","BIG5");
  65.     if(icv == 0)
  66.     {
  67.         printf("can't initalize iconv routine!/n");
  68.         return -1;
  69.     }
  70.     //enable "illegal sequence discard and continue" feature, so that if met illeagal sequence, 
  71.     //conversion will continue instead of being terminated
  72.     if(iconvctl (icv ,ICONV_SET_DISCARD_ILSEQ,&argument) != 0)
  73.     {
  74.         printf("can't enable /"illegal sequence discard and continue/" feature!/n");
  75.         return -1;
  76.     }
  77.     while(!feof(pSrcFile))
  78.     {
  79.         pSrcBuf = szSrcBuf;
  80.         pDstBuf = szDstBuf;
  81.         nDst = BUFFER_SIZE;
  82.         // read data from source file
  83.         nRead = fread(szSrcBuf + nSrc,sizeof(char),BUFFER_SIZE - nSrc,pSrcFile);
  84.         if(nRead == 0)
  85.             break;
  86.         // the amount of data to be converted should include previous left data and current read data
  87.         nSrc = nSrc + nRead; 
  88.         //perform conversion
  89.         nRet = iconv(icv,(const char**)&pSrcBuf,&nSrc,&pDstBuf,&nDst);
  90.         if(nRet == -1)
  91.         {
  92.             // include all case of errno: E2BIG, EILSEQ, EINVAL
  93.             //     E2BIG: There is not sufficient room at *outbuf.
  94.             //     EILSEQ: An invalid multibyte sequence has been encountered in the input.
  95.             //     EINVAL: An incomplete multibyte sequence has been encountered in the input
  96.             // move the left data to the head of szSrcBuf in other to link it with the next data block
  97.             memmove(szSrcBuf,pSrcBuf,nSrc);
  98.         }
  99.         //wirte data to destination file
  100.         fwrite(szDstBuf,sizeof(char),BUFFER_SIZE - nDst,pDstFile);
  101.         
  102.     }
  103.     iconv_close(icv);
  104.     fclose(pSrcFile);
  105.     fclose(pDstFile);
  106.     printf("conversion complete./n");
  107.     return 0;
  108. }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章