編碼問題:unicode與utf-8,wchar_t與char

以前一直用C++寫編程題,那些面向對象特性和一些泛性編程幾乎都沒有用到。現在靜下心來準備仔細研讀一下c++ primer。然後發現裏面講到一個wchar_t類型,兩個字節的數據類型,被設計用來存儲國際字符的。今天小試了一下發現不行,cout一直輸出不了,然後並沒有辦法按照想要的處理中文wchar_t數組。在網上搜了一下,發現這裏面關係到很多編碼的知識。趁這次機會一起梳理下。

1.編碼

大家經常看到utf-8編碼,都覺得這是文字編碼,然後又看到unicode編碼,GBK編碼等,腦子就凌亂了。這裏要說一下,其實unicode和GBK纔是編碼的值,這與計算機其實沒有什麼太多的關係,完全是數學處理。而utf-8和utf-16是討論的如何將unicode編碼存儲在計算機中以及如何在計算機中傳輸。簡單來說,unicode纔是編碼,而utf-8是存儲方式。GBK要轉utf-8必須先將其轉換成unicode編碼,然後再講unicode編碼存儲爲utf-8格式纔行。GBK只是對漢字的國際編碼格式,其實我個人覺得並沒有什麼前景(自從unicode編程流行以後)。我們還是主要關注一下unicode與utf-8的關係吧。

unicode編碼(16進制)   UTF-8 字節流(二進制)
0000 - 007F                0xxxxxxx
0080 - 07FF               110xxxxx 10xxxxxx
0800 - FFFF               1110xxxx 10xxxxxx 10xxxxxx

正如上面所示,在uft-8編碼其實得到的字節數不確定,可能是1個字節,也可能是3個字節。但utf-8最大的好處是和ASCII碼兼容,存儲英文字母都是一個字節,因此現在被廣泛應用。而uft-16編碼就目前應用來說和unicode編碼是完全一樣的。其不管存儲什麼字符都是用2個字節。所以大家就明白了,在英文比較多的地方,我們用utf-8編碼比較好,而在漢語或者其他國際字符比較多的情況下,我們用utf-16可以達到最小存儲。我覺得目前編碼掌握這些就可以了,其他的以後再慢慢研究吧大笑












2.大小端

在計算機存儲方式中,有大端存儲和小端存儲。intel的cpu是小端模式,而IBM的power是大端模式。

對於大端模式:

所謂的大端模式,是指數據的低位(就是權值較小的後面那幾位)保存在內存的高地址中,而數據的高位,保存在內存的低地址中,這樣的存儲模式有點兒類似於把數據當作字符串順序處理:地址由小向大增加,而數據從高位往低位放;

對於小端模式:

所謂的小端模式,是指數據的低位保存在內存的低地址中,而數 據的高位保存在內存的高地址中,這種存儲模式將地址的高低和數據位權有效地結合起來,高地址部分權值高,低地址部分權值低,和我們的邏輯方法一致。

舉個列子來說,

大家都知道字符‘A’的ASCII碼值爲65(十進制)也就是0x41,那麼這個值轉換成4字節的int型在不同大小端模式的系統中存放的方式分別爲:

大端模式:00 00 00 41  -----高低模式

小端模式:41 00 00 00  -----低高模式

對於一個字節內的數據,大小端是一樣的,八位爲00000000(高->低)

寫到這裏,我突然想起IEEE極限編程挑戰賽的時候,有道題裏面需要將char a[20]數組中的8個字節轉換成unsigned long long型的,當時我是用指針處理的,講頭指針放在&a[4]上面,然後強制轉換成unsigned long long型的,結果怎麼都不對,然後就火了,直接循環乘暴力轉換對了,不過那道題還有兩個test沒通過,不知道是怎麼回事?大哭

現在就知道當時指針轉換爲什麼不對了,就是小端問題,哎!!!只怪自己實力不行。

3.wchar_t型

wchar_t兩個字節,是C++用來存儲國際字符的數據類型,默認用unicode編碼保存。不過爲什麼在C++中,用cout流輸出不了呢?其實是cout流輸出時不是用的unicode編碼去讀取的,而是用的系統自帶的編碼格式,很是麻煩,而且不同的系統設置不一樣,windows是locale loc("chs");ubuntu是locale loc("zh_CN.UTF-8")

太蛋疼了,好吧,我覺得還是不要用C++處理中文了。。。尷尬具體的實現過程請各位自行百度吧,反正我是沒興趣了。還不如用java或者python3來的方便。java的char型是2個字節,python3默認編碼格式是unicode,爽歪歪。C++還是用來進行高性能編程的好!!!

最後發一個對C++中文輸出吐槽的圖片聊以慰藉一下。











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