GBK和UTF8之間的轉換可以使用MultiByteToWideChar和WideCharToMultiByte兩個API,方法是先把它們轉換為中間編碼Unicode,再轉換為對應的編碼即可。
#include < stdio.h >
#include < windows.h >
// GBK編碼轉換到UTF8編碼
int GBKToUTF8(unsigned char * lpGBKStr,unsigned char * lpUTF8Str, int nUTF8StrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0 ;
if ( ! lpGBKStr) // 如果GBK字元串為NULL則出錯退出
return 0 ;
nRetLen = ::MultiByteToWideChar(CP_ACP, 0 ,( char * )lpGBKStr, - 1 ,NULL,NULL); // 擷取轉換到Unicode編碼後所需要的字元空間長度
lpUnicodeStr = new WCHAR[nRetLen + 1 ]; // 為Unicode字元串空間
nRetLen = ::MultiByteToWideChar(CP_ACP, 0 ,( char * )lpGBKStr, - 1 ,lpUnicodeStr,nRetLen); // 轉換到Unicode編碼
if ( ! nRetLen) // 轉換失敗則出錯退出
return 0 ;
nRetLen = ::WideCharToMultiByte(CP_UTF8, 0 ,lpUnicodeStr, - 1 ,NULL, 0 ,NULL,NULL); // 擷取轉換到UTF8編碼後所需要的字元空間長度
if ( ! lpUTF8Str) // 輸出緩沖區為空則傳回轉換後需要的空間大小
{
if (lpUnicodeStr)
delete []lpUnicodeStr;
return nRetLen;
}
if (nUTF8StrLen < nRetLen) // 如果輸出緩沖區長度不夠則退出
{
if (lpUnicodeStr)
delete []lpUnicodeStr;
return 0 ;
}
nRetLen = ::WideCharToMultiByte(CP_UTF8, 0 ,lpUnicodeStr, - 1 ,( char * )lpUTF8Str,nUTF8StrLen,NULL,NULL); // 轉換到UTF8編碼
if (lpUnicodeStr)
delete []lpUnicodeStr;
return nRetLen;
}
// UTF8編碼轉換到GBK編碼
int UTF8ToGBK(unsigned char * lpUTF8Str,unsigned char * lpGBKStr, int nGBKStrLen)
{
wchar_t * lpUnicodeStr = NULL;
int nRetLen = 0 ;
if ( ! lpUTF8Str) // 如果UTF8字元串為NULL則出錯退出
return 0 ;
nRetLen = ::MultiByteToWideChar(CP_UTF8, 0 ,( char * )lpUTF8Str, - 1 ,NULL,NULL); // 擷取轉換到Unicode編碼後所需要的字元空間長度
lpUnicodeStr = new WCHAR[nRetLen + 1 ]; // 為Unicode字元串空間
nRetLen = ::MultiByteToWideChar(CP_UTF8, 0 ,( char * )lpUTF8Str, - 1 ,lpUnicodeStr,nRetLen); // 轉換到Unicode編碼
if ( ! nRetLen) // 轉換失敗則出錯退出
return 0 ;
nRetLen = ::WideCharToMultiByte(CP_ACP, 0 ,lpUnicodeStr, - 1 ,NULL,NULL,NULL,NULL); // 擷取轉換到GBK編碼後所需要的字元空間長度
if ( ! lpGBKStr) // 輸出緩沖區為空則傳回轉換後需要的空間大小
{
if (lpUnicodeStr)
delete []lpUnicodeStr;
return nRetLen;
}
if (nGBKStrLen < nRetLen) // 如果輸出緩沖區長度不夠則退出
{
if (lpUnicodeStr)
delete []lpUnicodeStr;
return 0 ;
}
nRetLen = ::WideCharToMultiByte(CP_ACP, 0 ,lpUnicodeStr, - 1 ,( char * )lpGBKStr,nRetLen,NULL,NULL); // 轉換到GBK編碼
if (lpUnicodeStr)
delete []lpUnicodeStr;
return nRetLen;
}
// 使用這兩個函數的例子
int main()
{
char cGBKStr[] = " 我是中國人! " ;
char * lpGBKStr = NULL;
char * lpUTF8Str = NULL;
FILE * fp = NULL;
int nRetLen = 0 ;
nRetLen = GBKToUTF8((unsigned char * )cGBKStr,NULL,NULL);
printf( " 轉換後的字元串需要的空間長度為:%d " ,nRetLen);
lpUTF8Str = new char [nRetLen + 1 ];
nRetLen = GBKToUTF8((unsigned char * )cGBKStr,(unsigned char * )lpUTF8Str,nRetLen);
if (nRetLen)
{
printf( " GBKToUTF8轉換成功! " );
}
else
{
printf( " GBKToUTF8轉換失敗! " );
goto Ret0;
}
fp = fopen( " C:/GBK轉UTF8.txt " , " wb " ); // 儲存到文本檔案
fwrite(lpUTF8Str,nRetLen, 1 ,fp);
fclose(fp);
getchar(); // 先去打開那個文本檔案看看,單擊記事本的“檔案”-“另存為”菜單,在對話框中看到編碼框變為了“UTF-8”說明轉換成功了
nRetLen = UTF8ToGBK((unsigned char * )lpUTF8Str,NULL,NULL); // 再轉回來
printf( " 轉換後的字元串需要的空間長度為:%d " ,nRetLen);
lpGBKStr = new char [nRetLen + 1 ];
nRetLen = UTF8ToGBK((unsigned char * )lpUTF8Str,(unsigned char * )lpGBKStr,nRetLen);
if (nRetLen)
{
printf( " UTF8ToGBK轉換成功! " );
}
else
{
printf( " UTF8ToGBK轉換失敗! " );
goto Ret0;
}
fp = fopen( " C:/UTF8轉GBK.txt " , " wb " ); // 儲存到文本檔案
fwrite(lpGBKStr,nRetLen, 1 ,fp);
fclose(fp);
getchar(); // 再去打開文本檔案看看,發現編碼框又變為了“ANSI”說明轉換成功了
Ret0:
if (lpGBKStr)
delete []lpGBKStr;
if (lpUTF8Str)
delete []lpUTF8Str;
return 0 ;
}
在網上看到的一些文章說,UTF8轉換為GBK的時候會有問題,特别是當UTF8字元串中的漢字數為奇數時。關于這個問題我沒有去驗證過,而且我對UTF8和GB2312的編碼還不是很熟悉,呵呵,等以後有空的時候再去了解一下編碼吧。