C 讀寫unicode文字

2021-06-02 09:59:26 字數 2801 閱讀 5802

熟悉一下字元型別,char, wchar_t, tchar,最熟悉的char是單位元組字元,適用於ansi編碼;wchar_t是雙位元組的寬字元型別,適用於unicode編碼;tchar是乙個巨集,在ansi壞境下定義為char,unicode壞境下定義為wchar_t。

怎麼來表示字串?對,字元陣列,要知道在c++語言裡面,其實沒有陣列的資料結構,所謂陣列,都是由指標+長度來表示。字元型指標const char *, const wchar_t *, const tchar *可以用來在不同的環境下表示字串。再說相關的幾個巨集,lpstr: long point string, 相當於char *; lpcstr: long point const string, 相當於 const char *; lpcwstr: long point const wide string, 相當於 const wchar_t *; lpctstr: 類似的,相當於 const tchar *; 這些都不要死記硬背,記著大寫字母的意思即可猜出其含義。

乙個字串,比如說"北京2008",對應ansi編碼表示為 const char * cha = "北京2008"; unicode編碼表示為 const wchar_t * wcha = l"北京2008"; 。在記憶體裡以二進位制儲存,ansi編碼對應為 0x b1b1 bea9 32 30 30 38,unicode編碼為 0x 1753 ac4e 3200 3000 3000 3800。

回到上面,為什麼字元型指標可以表示乙個字串?計算機找到這個指標,只能知道串首字元,這裡因為字串有個預設的結束符'\0'(ansi或者ascii表示為0x00),從首字元開始,計算機開始向後查詢直到0x00,認為字串結束,所以儲存字串的時候,計算機是帶著乙個特殊結束符的。可是要注意了,這個結束符0x00是ascii碼定義的結束符啊,那麼在寬字元unicode環境下呢?結束符是什麼?是0x0000。

而對於非const字串,怎麼表示?char * 方法怎麼動態定義長度?好辦,可以用new手動分配記憶體空間,除此之外,還有更好辦的方法,那就是字串型別string, 怎麼可變長度,怎麼記錄長度,記憶體怎麼儲存,這些都不用管,都有c++標準庫自動管理。

不同型別的字串間之間怎麼轉換?比如定義 char * cha; string str; str = cha; // 可以實現 char * 到 string 的轉換, cha = str.c_str(); 可以從 string 轉換到 char *;對於wchar_t wcha; wstring wstr; 呢?wstr = wcha; wcha = wstr.c_str(); // 這個是否可以呢?!

說過了字串的表示和型別轉換,再來看字元流i/o,c++裡面的fstream, ifstream, ofstream, 檔案流的i/o有好多種方式,預設為字元流方式,明確的說是ansi字元流,都是針對ansi文字的,那麼unicode怎麼讀寫呢?

c++裡倒真有wfsteam流的,可惜用起來也很奇怪,用wifstream讀取unicode文字,結果竟然是讀取乙個位元組,加上乙個0x00,在讀取下乙個位元組,如此!比如文字裡儲存的還是「北京2008」,剛才說過unicode編碼為 0x 1753 ac4e 3200 3000 3000 3800;用wifstream讀到記憶體的字元竟是 0x 1700 5300 ac00 4e00 ... 這叫什麼unicode?我不知道wfstream怎麼正確使用用,有知道的朋友還請不吝告知!

既然wftream不行,那麼怎麼讀取unicode呢,這裡可以借鑑一下二進位製流的讀寫方式,二進位製流在讀寫時必須明白儲存單位的資料結構,定義為結構體,然後逐n位元組(n為結構長度)按二進位制讀取;這個可以借鑑過來,不用定義結構了,直接用wchar_t,**如下:

ifstream fin;

fin.open(filename, ios::binary);

// 跳過unicode文字開頭有兩個位元組0xfffe(稱作bom,用於標識unicode編碼)

fin.seek(2, ios::beg);

while (!fin.eof())

如果要按行讀取,怎麼辦?好了,有ifstream的成員函式getline(cha, size),還有string類成員函式getline(fin, str)。你試試能不能用在unicode下使用?答案是否定的!為什麼?因為getline函式預設在ansi下使用,它對換行符的判斷是基於ascii碼的換行(0x0d)和行開頭標記(0x0a),如果把它用在unicode編碼下,比如「不」字,unicode編碼為0x0d4e。當getline函式執行到這,以為換行了,所以說會失效!那麼unicode換行符以及行開頭符的二進位制是什麼?雙位元組了,是0x0d00和0x0a00,這時候getline函式就失效了,怎麼辦,手動判斷:

ifstream fin;

fin.open(filename, ios::binary);

size_t index = 2;

while (!fin.eof())

else

}上面的程式可以讀取unicode了,那麼讀了進來怎麼理解unicode呢,這就需要char * 和 wchar_t *間的轉換了,這個沒有簡便的方法,ansi、unicode兩種編碼之間的轉換,只能靠查表實現,c++提供了兩個函式,wcstombs(_dest, _source, _dsize) 從unicode編碼轉化為ansi編碼 ,mbstowcs(_dest, _source, _dsize)反之,引數對應為const char*, const wchar_t*以及長度。這裡在提供乙個網上的函式,用於實現string和wstring的轉換:

std::string ws2s(const std::wstring& ws)

std::wstring s2ws(const std::string& s)

寫到這裡,就可以用c++讀取unicode文字了,寫的方法類似。

用C 讀寫unicode文字

用c 讀寫unicode文字 致敬原作者 http librawill.blogspot.com 2008 08 cunicode 2881.html 熟悉一下字元型別,char,wchar t,tchar,最熟悉的char是單位元組字元,適用於ansi編碼 wchar t是雙位元組的寬字元型別,適...

用C 讀寫unicode文字

字元型別 char,wchar t,tchar,最熟悉的char是單位元組字元,適用於ansi編碼 wchar t是雙位元組的寬字元型別,適用於unicode編碼 tchar是乙個巨集,在ansi壞境下定義為char,unicode壞境下定義為wchar t。怎麼來表示字串?對,字元陣列,要知道在c...

c 檔案讀寫 文字讀寫

include int main else return 0 格式 intfscanf file stream,constchar format,返回值 如果成功,該函式返回成功匹配和賦值的個數。如果到達檔案末尾或發生讀錯誤,則返回 eof 引數1 file stream 檔案指標 引數2 cons...