這裡以Code::Blocks 10.5版本為藍本進行說明。
首先,請在Code::Blocks裡面輸入標準的一個C程式:
#include<stdio.h><br />#include<stdlib.h><br />#include<wchar.h><br />#include<string.h><br />#include<locale.h><br />int main(void)<br />{</p><p> char str[]="中國china";<br /> wchar_t str_w[]=L"中國china";</p><p> int len=(int)strlen(str);<br /> int len_w=(int)wcslen(str_w);<br /> printf("%s,size=%d/n",str,len);</p><p> setlocale(LC_ALL, "chs");<br /> wprintf(L"%s,size=%d/n",str_w,len_w);</p><p> system("pause");<br /> return 0;<br />}</p><p>
然後選用不同的編譯器,觀看效果。
1.Tiny C
編譯沒問題,但是wprintf是顯示不出內容的。注釋掉setlocale(LC_ALL,"chs“)之後,wprintf顯示出和printf一樣的效果。
結果證明,Tinny C是不真正的支援wchar_t寬字元集。因為通過調試器,我發現他的wchar_t裡面儲存的字元每個字元確實是用2個位元組了,但是裡面編碼依然是ANSI編碼,並不是unicode代碼,所以setlocale(LC_ALL,"chs“)+wprintf顯示不出來(其實wprintf實現的時候,是不會直接輸出unicode的,他實際是先把unicode轉成多位元組的ANSI編碼,然後再輸出,和printf原理一樣,就是多了一個轉碼過程,所以你使用之前必須先設定locale,否則他不知道如何轉,就輸不出來)。
雖然他自稱部分支援C99,但是至少在寬字元方面,支援的一點都不好。
Tinny C有一點好,他沒有亂碼,他要麼不顯示,要麼正常顯示。
2.VC2005-2010
一切OK,沒有亂碼。是支援wchar_t支援的最好的!
3.GCC(MinGW)
很遺憾,全是亂碼!和java 一個德行(相信用過Java的人一定會想起Java的亂碼解決花費的時間吧)。呵呵。但是GCC是支援wchar_t的,為什麼會這樣?其實根本原因就是:本地化做的不好。
但是解決方案是有的。
要解決這個問題,先要搞清楚有三個地方涉及到編碼問題。
1.Code::Blocks 編輯器儲存源檔案用的編碼。
預設情況下,是儲存為windows本地編碼的,也就是WINDOWS-936字元集,也就是GBK編碼。
但是很神奇的是,GCC編譯器預設編譯的時候是按照UTF-8解析的。你存成GBK,但是當成UTF-8解析,這還能編譯通過,這才有鬼了,所以這兩個地方編碼不統一好,編譯的時候報錯:error: converting to execution character set: Illegal byte sequence,你根本連通過編譯的可能性都沒有!
其實要解決這個問題很簡單,編寫Code::Blocks的人只需要在調用編譯器之前檢測一下源檔案是什麼編碼,然後就自動讓編譯器用什麼編碼進行解釋,問題就解決了。只是很可惜,Code::Blocks編寫的人可能還沒有這麼做,或許是對本地化認識不夠吧,也可能是覺得沒必要吧?(所以就給初學的人帶來問題了,所以就覺得易用性不如微軟了,免費和商業的東西還是有差距的。。。)
2。GCC編譯器編譯的時候對輸入的源檔案解釋用的編碼
這個編譯器可以設定-finput-charset=charset來指定編譯器用什麼編碼解釋輸入源檔案。比如如果源檔案的字元集是GBk,那麼就必須指定-finput-charset=GBK,如果不指定,一律當做UTF-8處理。
除非你源檔案真的是UTF-8,否則就會出現轉換錯誤。
3。編譯好的執行檔案所用編碼
如果你1和2兩個地方的編碼都能統一,那麼編譯時間不會報錯了,但是編譯好了,運行一下看看,在控制台顯示的依然是亂碼!
那是因為控制台顯示的時候預設的是使用系統預設的字元集,比如windows下用的是GBk,但是預設情況下,編譯之後的執行檔案時編譯成UTF-8的,所以又出現了不統一,亂碼由此而生!
解決的方法和簡單,就是給編譯器加上選項:-fexec-charset=GBK,和windows預設的統一,就OK了。
搞懂了亂碼產生的原因,那麼不難得出結論,如何修改,你想修改成什麼都OK,關鍵是要統一,並不是像網上一些人說的,修改成GBK就OK,其實你要修改成UTF-8都OK,關鍵是統一。
下面說說修改的地方。
1。修改源檔案儲存編碼在:settings->Editor->gernal settings 看到右邊的Encoding group Box了嗎?如所示:
Use encoding when opening files:這個表示開啟檔案用的格式,第一次儲存檔案的時候也會用這個格式。
As default encoding:表示設定為檔案預設儲存和開啟編碼格式
注意,要先設定好,然後儲存檔案,才有效。如果你已經儲存了檔案,無論你怎麼修改這個設定,也不會改變你檔案的格式了。你的檔案還是保持第一次儲存的時候的格式。
所以,如果遇到無法生效,只能先設定好格式,再重建立檔案了。
2。修改編譯器對源檔案解釋編碼格式和產生執行檔案執行時候採用的編碼格式
是在settings->compiler and debugger settings裡面,選擇對應的GCC編譯器,如所示:
在other options裡面加入:
-finput-charset=charset
-fexec-charset=charset
第一個參數表示編譯的時候輸入檔案的編碼解釋格式,第二參數表示產生的執行檔案執行的時候顯示用的編碼格式。
這些參數如果和實際不吻合,必然產生亂碼。只要吻合,就不會亂碼了。
由於我的源檔案格式是WINDOWS-936,但是這裡設定成UTF-8,所以編譯肯定報錯!
只需要修改成-finput-charset=WINDOWS-936或者GBk,就編譯通過了。
如果不設定fexec-charset預設會認為執行環境是UTF-8,而windows下並不是,所以Linux下沒問題,因為Linux就是UTF-8的,但是windows 下必然出現亂碼。
所以設定成GBk,就統一了。
一切都那麼簡單,其實,只是因為編程的人做的不夠完善,所以才會給使用的人帶來困擾。希望這篇文章能幫到一些初學者。或者遇到同樣問題的人。