vs從文件中讀取中文亂碼問題解決


問題導入:

有同學讓我教教他C語言的文件操作,他的要求是從文件中讀取幾個學生的姓名和年級信息到結構體中,我想這豈不是非常簡單嘛。當場碼代碼給他看,結果翻車了。當文件中的姓名和年級信息都為英文的時候,表現一切良好,然后當我把姓名和年級信息改為中文時,在vs控制台上輸出卻發生了亂碼。當時有點尷尬,這個問題我以前也碰到過,在當時也貌似解決了,而且我也知道這是編碼不一致的問題,但要望具體了說,卻無從下口。到底是編碼哪里不一致呢?

編碼問題:

眾所周知,計算機只能處理數字,要想處理文本,就要將文本給轉換為數字,而編碼方式就是將01的數字轉化為文本的橋梁。編碼的方式,有很多很多種,我在此整理了最常用的幾種編碼方式(下面的內容我取於360百科,並作出自己的一些理解):

ascll碼

ASCll是基於拉丁字母的一套電腦編碼系統,主要用於顯示現代英語和其他西歐語言。ascll用一個字節八位來表示一個字符,因為每個位的狀態僅有0和1,因此ascll理論上可以表示256個字符。但ascll碼統一將最前的一位設置為0,因此ascll碼一共規定了128個字符。例如字符0對應的ascll碼是112對應十六進制70對應二進制01110000.

ansi編碼

最開始美國人把ascll碼的0到128位中放置了所有的英文字母和一些符號和無法打印的符號,覺得應用起來綽綽有余。但隨着計算機的推廣,歐洲語言雖然都是字母自稱,各國的字母又是各不相同,於是將128位到256位空置的位進行擴展。然后計算機到了中國,256個字符遠遠滿足不了使用需求,就用兩個字節了表示字符。稱為GBK編碼。到日本,日本人又用 Shift_JIS 。於是,各個國家都用這屬於自己語言的編碼。不管是GBK編碼還是 Shift_JIS 編碼,我們都稱之為ANSI編碼。對於ANSI編碼在0x00~0x7F之間的字符,依舊是1個字節代表1個字符,這點與ascll碼無異。

Unicode編碼

為了統一所有文字的編碼,Unicode應運而生。Unicode把所有語言都統一到一套編碼里,這樣就不會再有亂碼問題了。Unicode是國際組織制定的可以容納世界上所有文字和符號的字符編碼方案。目前的Unicode字符分為17組編排,0x0000 至 0x10FFFF,每組稱為平面(Plane),而每平面擁有65536個碼位,共1114112個。另外

UTF-8編碼

然而Unicode盡管統一了編碼,但它卻並未指明編碼該如何實現例如漢字宏的Unicode編碼是:5B8F(0101 1011 1000 1111),然后我們在解碼的時候如何知道這兩個字節是對應的一個漢字(宏)還是兩個ascll碼([ 和 8F(未定義))呢?於是乎,需要一個能夠實現unicode編碼的編碼形式。實現Unicode編碼的方法有UTF-8、UTF-16、UTF-32,這里說明UTF-8.
UTF-8b編碼規則
1)對於單字節的符號,字節的第一位設為0,后面7位為這個符號的 Unicode 碼。因此對於英語字母,UTF-8 編碼和 ASCII 碼是相同的。

2)對於n字節的符號(n > 1),第一個字節的前n位都設為1,第n + 1位設為0,后面字節的前兩位一律設為10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。
unicode與UFT-8轉化表
| unicode (十六進制) | UTF-8 (二進制) |
| 00 00 00 - 00 00 7F | 0xxx xxxx |
| 00 00 80 - 00 07 FF | 110xxxxx 10xxxxxx |
| 00 08 00 - 00 FF FF | 1110xxxx 10xxxxxx 10xxxxxx |
| 01 00 00 - 10 FF FF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx|

問題的解決

搞明白以上幾個點之后 ,我回過頭了看我的那個亂碼問題,首先我觀察到我的記事本的編碼形式是UTF-8,在UTF-8編碼中 宏 對應E5AE8F,而 五 對應E4BA94.然后我又觀察到我的microsoft visual studio 的控制台的代碼頁是 936(ANSI/OEM - 簡體中文 GBK)兩個的編碼形式不同自然會亂碼。GBK用兩個字節來表示一個中文,因此我們取出宏對應的E5AE8F前兩位 E5AE 轉化為gb2312編碼得到漢字瀹 將五 對應E4BA94 取出前兩位 E4BA 得到浜,剩下的兩個1位8F 94超過了7F不是ascll編碼,而且只有一位也不是gb2312編碼,因而查無此編碼輸出?。所以解決的辦法是,將控制台和記事本編碼方式對應,將記事本另存為編碼方式為ANSI即可。


執行代碼:

問題解決!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM