《UTF-8與GB2312之間的互換》的改進[原創]

來源:互聯網
上載者:User

《UTF-8與GB2312之間的互換》的改進

作者:李天助

下載原始碼

  最近,在做一個小程式的時候,突然遇到了漢字編碼轉換問題。關於如何在UTF-8與GB2312之間轉換的問題。在VC知識庫裡看到吳康彬的文章《UTF-8與GB2312之間的互換》,文章淺顯易懂,代碼也不長。省了我不少的找資料的時間。在此謝謝了。 :)
  在看代碼的過程中,吳康彬用了許多字串的轉換,來進行2進位的運算,這就涉及到大量的IO操作,效率肯定比較低。而且編碼轉換的工作量往往非常大,因此效率問題很重要。而且,代碼裡,有許多,記憶體流失問題,可能是作者過於重視實現,沒有注意這些細節問題。
  閑話少說,開始正題。在UTF-8,與UNICODE之間轉換的時候,用二進位運算,代替了字串的轉換。UTF-8一個漢字,用3個位元組,而UNICODE用2個位元組;對應關係如下:

UTF-8編碼:               [1,1,1,0,A5,A6,A7,A8],    [1,0,B3,B4,B5,B6,B7,B8],                  [1,0,C3,C4,C5,C6,C7,C8];

對應的UNICODE編碼:

[A5,A6,A7,A8,B3,B4,B5,B6],               [B7,B8,C3,C4,C5,C6,C7,C8]

因此我們只需進行位操作,即可達到目的;如:

      // 把UTF-8轉換成Unicode      void CChineseCodeLib::UTF_8ToUnicode(WCHAR* pOut,char *pText)      {      char* uchar = (char *)pOut;           uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);      uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);           return;      }
     // Unicode 轉換成UTF-8      void CChineseCodeLib::UnicodeToUTF_8(char* pOut,WCHAR* pText)     {      // 注意 WCHAR高低字的順序,低位元組在前,高位元組在後      char* pchar = (char *)pText;      pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));      pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);      pOut[2] = (0x80 | (pchar[0] & 0x3F));      return;     }     
     // 把Unicode 轉換成 GB2312      void CChineseCodeLib::UnicodeToGB2312(char* pOut,unsigned short uData)     {     WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);     return;     }          
     // GB2312 轉換成 Unicode     void CChineseCodeLib::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)     {     ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);     return;     }     
     //GB2312 轉為 UTF-8     void CChineseCodeLib::GB2312ToUTF_8(string& pOut,char *pText, int pLen)     {           char buf[4];           char* rst = new char[pLen + (pLen >> 2) + 2];                      memset(buf,0,4);           memset(rst,0,pLen + (pLen >> 2) + 2);                      int i = 0;           int j = 0;                 while(i < pLen)           {                   //如果是英文直接複製就可以                   if( *(pText + i) >= 0)                   {                           rst[j++] = pText[i++];                   }                   else                   {                           WCHAR pbuffer;                           Gb2312ToUnicode(&pbuffer,pText+i);                                                      UnicodeToUTF_8(buf,&pbuffer);                                                      unsigned short int tmp = 0;                           tmp = rst[j] = buf[0];                           tmp = rst[j+1] = buf[1];                           tmp = rst[j+2] = buf[2];                                                                                 j += 3;                           i += 2;                   }           }           rst[j] = '/0';              //返回結果           pOut = rst;                        delete []rst;                         return;     }     
     //UTF-8 轉為 GB2312     void CChineseCodeLib::UTF_8ToGB2312(string &pOut, char *pText, int pLen)     {         char * newBuf = new char[pLen];         char Ctemp[4];         memset(Ctemp,0,4);         int i =0;         int j = 0;                  while(i < pLen)         {                if(pText[i] > 0)                {                        newBuf[j++] = pText[i++];                                       }                else                                 {                        WCHAR Wtemp;                        UTF_8ToUnicode(&Wtemp,pText + i);                                        UnicodeToGB2312(Ctemp,Wtemp);                                            newBuf[j] = Ctemp[0];                        newBuf[j + 1] = Ctemp[1];                        i += 3;                            j += 2;                   }         }         newBuf[j] = '/0';                  pOut = newBuf;         delete []newBuf;                  return;      }

  代碼在WIN2K,VC++60 下編譯,測試通過. 就說這麼多吧,具體的大家看代碼吧。草草的寫的,大家莫笑,歡迎大家一起討論; 覺覺羅。。。。

-----------------------------------------------------------------------------------------------------------------------------------------

原始碼:

// ChineseCodeLib.h: interface for the CChineseCodeLib class.
//
//////////////////////////////////////////////////////////////////////
#include<string>
using namespace std;

/*
功能:漢字GB2312與UTF-8編碼互轉
作者:litz
Email:mycro@163.com
參考:吳康彬先生的文章《UTF-8與GB2312之間的互換》
http://www.vckbase.com/document/viewdoc/?id=1397
*/

#if !defined(__CCHINESECODELIB_H_)
#define __CCHINESECODELIB_H_

class CChineseCodeLib
{
public:
 static void UTF_8ToGB2312(string& pOut,char *pText, int pLen);
 static void GB2312ToUTF_8(string& pOut,char *pText, int pLen);
 // Unicode 轉換成UTF-8
 static void UnicodeToUTF_8(char* pOut,WCHAR* pText);
 // GB2312 轉換成 Unicode
 static void Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer);
 // 把Unicode 轉換成 GB2312
 static void UnicodeToGB2312(char* pOut,unsigned short uData);
 // 把UTF-8轉換成Unicode
 static void UTF_8ToUnicode(WCHAR* pOut,char* pText);

 CChineseCodeLib();
 virtual ~CChineseCodeLib();
};

#endif // !defined(__CCHINESECODELIB_H_)

//-----------------------------------------------------------------------------

// ChineseCodeLib.cpp: implementation of the CChineseCodeLib class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ChineseCodeLib.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CChineseCodeLib::CChineseCodeLib()
{

}

CChineseCodeLib::~CChineseCodeLib()
{

}

void CChineseCodeLib::UTF_8ToUnicode(WCHAR* pOut,char *pText)
{
 char* uchar = (char *)pOut;
 
 uchar[1] = ((pText[0] & 0x0F) << 4) + ((pText[1] >> 2) & 0x0F);
 uchar[0] = ((pText[1] & 0x03) << 6) + (pText[2] & 0x3F);

 return;
}

void CChineseCodeLib::UnicodeToGB2312(char* pOut,unsigned short uData)
{
 WideCharToMultiByte(CP_ACP,NULL,&uData,1,pOut,sizeof(WCHAR),NULL,NULL);
 return;
}

void CChineseCodeLib::Gb2312ToUnicode(WCHAR* pOut,char *gbBuffer)
{
 ::MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,gbBuffer,2,pOut,1);
 return;
}

void CChineseCodeLib::UnicodeToUTF_8(char* pOut,WCHAR* pText)
{
 // 注意 WCHAR高低字的順序,低位元組在前,高位元組在後
 char* pchar = (char *)pText;

 pOut[0] = (0xE0 | ((pchar[1] & 0xF0) >> 4));
 pOut[1] = (0x80 | ((pchar[1] & 0x0F) << 2)) + ((pchar[0] & 0xC0) >> 6);
 pOut[2] = (0x80 | (pchar[0] & 0x3F));
 
 return;
}

void CChineseCodeLib::GB2312ToUTF_8(string& pOut,char *pText, int pLen)
{
 char buf[4];
 char* rst = new char[pLen + (pLen >> 2) + 2];
 
 memset(buf,0,4);
 memset(rst,0,pLen + (pLen >> 2) + 2);
 
 int i = 0;
 int j = 0; 
 while(i < pLen)
 {
  //如果是英文直接複製就可以
  if( *(pText + i) >= 0)
  {
   rst[j++] = pText[i++];
  }
  else
  {
   WCHAR pbuffer;
   Gb2312ToUnicode(&pbuffer,pText+i);
   
   UnicodeToUTF_8(buf,&pbuffer);
   
   unsigned short int tmp = 0;
   tmp = rst[j] = buf[0];
   tmp = rst[j+1] = buf[1];
   tmp = rst[j+2] = buf[2];
   
   
   j += 3;
   i += 2;
  }
 }
 rst[j] = '/0';

 //返回結果
 pOut = rst;  
 delete []rst; 
 
 return;
}

void CChineseCodeLib::UTF_8ToGB2312(string &pOut, char *pText, int pLen)
{
  char * newBuf = new char[pLen];
  char Ctemp[4];
  memset(Ctemp,0,4);

  int i =0;
  int j = 0;
 
  while(i < pLen)
  {
   if(pText[i] > 0)
  {
   newBuf[j++] = pText[i++];   
  }
  else                
  {
   WCHAR Wtemp;
   UTF_8ToUnicode(&Wtemp,pText + i);
  
   UnicodeToGB2312(Ctemp,Wtemp);
     
   newBuf[j] = Ctemp[0];
   newBuf[j + 1] = Ctemp[1];

   i += 3;   
   j += 2;  
  }
  }
  newBuf[j] = '/0';
 
  pOut = newBuf;
  delete []newBuf;
 
  return;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.