1. 程式人生 > >wchar與char字元轉換的探究

wchar與char字元轉換的探究

在Xcode 模擬器環境下,測試wchar_t與char的轉換:

void convert_test()
{
    setlocale(LC_ALL, "zh_CN.UTF-8");
    char*    src_str = "中國";
    wchar_t* src_wstr = L"中國";
    
    char*    dest_str = malloc(32);
    wchar_t* dest_wstr = malloc(32);
    
    mbstowcs(dest_wstr, src_str, mbstowcs(NULL, src_str, 100));
    wcstombs(dest_str, src_wstr, wcstombs(NULL, src_wstr, 100));
    
    free(dest_str);
    free(dest_wstr);
}

這裡遇到兩個疑問:

1.  字串儲存時的編碼格式由什麼決定?

2.  wcstombs()和mbstowcs()這兩個函式對編碼格式進行了什麼樣的轉換?

其中,漢字"中“、“國”的編碼如下:

GB2312  Unicode UTF-8        D6D0     4E2D       E4 B8 AD  中 B9FA     56FD       E5 9B BD  國

第1個問題,根據C/C++編譯策略,字串的編碼方式由原始檔格式決定(http://www.cppblog.com/lf426/archive/2010/06/25/118707.html);我們來根據測試結果證實一下:

當原始檔格式是UTF-8時:

 [1]  src_str 記憶體資料  :    0x0010139e: e4 b8 ad e5 9b bd 00 6c 65 6e 20 3d 20 25 64 0a  .......len = %d.

 [2]  src_wstr 記憶體資料:    0x00101abc: 2d 4e 00 00 fd 56 00 00 00 00 00 00 01 00 00 00  -N...V..........

當原始檔格式是GB2312時:

[3] src_str在記憶體中的結果:    0x000b6906: d6 d0 b9 fa 00 6c 65 6e 20 3d 20 25 64 0a 00 63  .....len = %d..c

[4] GB2312的檔案格式下,漢字無法以寬字元的格式儲存,編譯錯誤; 

從上面的結果[1]中可以看到,在UTF-8格式原始檔中,以char格式儲存的字串, 從低到高是"e4 b8 ad e5 9b bd",剛好是"中國"的UTF-8編碼按位元組由低到高儲存的格式(不存在位元組序的問題); 而[3]中可以看出, char字串儲存的剛好是"中國“的GB2312編碼,與原始檔格式一致,每位元組分開儲存(也不存在位元組序的問題); 從[2]中可以看到,wchar_t格式的資料"2d 4e 00 00 fd 56 00 00"剛好是“中國”的Unicode編碼,而且是小端格式; 因此,結論是當以char型別儲存中文字元的時候,編碼式由原始檔的編碼格式決定;而wchart_t型別的寬字元都以Unicode編碼的方式儲存; 

第2個問題, C標準庫函式mbstowcs()和wcstombs()對編碼轉換具體進行了什麼操作?根據手冊,我們知道mbstowcs()將char型別的字串轉換成wchart_t型別的字串,wcstombs()則相反; 因為這兩個函式依賴於本地化策略,所以需要先呼叫setLocale(),首先設定成"zh_CN.UTF-8"格式,得到轉換後的資料: 

[5]  dest_str記憶體資料: 0x7a946520: e4 b8 ad e5 9b bd d8 01 00 00 93 7a 0d 00 93 7a  ...........z...z

[6] dest_wstr記憶體資料:0x7a822b50: 2d 4e 00 00 fd 56 00 00 0e 42 6c 61 63 6b 5f 31  -N...V...Black_1

從[5]可以看到wcstombs()函式將寬位元組表示的"中國"轉換後的結果就是其UTF-8編碼; [6]中可以看出,mbstowcs()實際上將UTF-8表示的”中國“轉換成了其對應的Unicode編碼; 這正好是字元在char型別下的編碼方式與wchar_t型別下的編碼方式間的相互轉換。

(轉載請註明出處:http://blog.csdn.net/codigger/article/details/40711103)