win和linux平臺(tái)下C++ 字符串的編碼分享
windows平臺(tái)
char 表示單字符,占用一個(gè)字節(jié)
wchar_t 表示寬字符,占用兩個(gè)字節(jié)
Linux平臺(tái)
char 占用一個(gè)字節(jié)
wchar_t 占用四個(gè)字節(jié)
windows平臺(tái)下對(duì)于用字符串保存中文的問題,GBK和UTF8都是用char來表示,只是為了表示一個(gè)中文字符需要用到多個(gè)char。而對(duì)于UNICODE(其實(shí)應(yīng)該說是UFT16),每一個(gè)字符都需要一個(gè)兩個(gè)字節(jié),也就是用wchar_t表示。
UNICODE只是一個(gè)字符集,規(guī)定了不同的字符對(duì)應(yīng)于一個(gè)唯一的整數(shù),平時(shí)所說的使用UNICODE編碼其實(shí)說的是UFT16編碼(顧名思義就是用16位來表示一個(gè)字符)。
UTF8、UTF16和UFT32則是基于UNICODE字符集的三種編碼方式。不同之處是:對(duì)于一個(gè)字符所對(duì)應(yīng)的整數(shù),應(yīng)該怎樣用二進(jìn)制位表示出來。對(duì)于UTF16和UTF32,不管字符對(duì)應(yīng)的數(shù)字是多少,都用恒定的多字節(jié)表示,所以可以很方便的表示一個(gè)字符,但需要注意字節(jié)序問題。比較麻煩的是UFT8,對(duì)于不同的字符,可能會(huì)用到一個(gè)字節(jié),兩個(gè)字節(jié)到最多六個(gè)字節(jié)。這么做的好處是節(jié)省了空間。
在實(shí)際使用字符串保存時(shí),因?yàn)閁TF16不管什么字符,都用2個(gè)字節(jié)表示,所以可能會(huì)出現(xiàn)某一個(gè)字節(jié)全零的情況。例如字符‘A’編碼是0x41,用UTF16表示就是0x0041。對(duì)于char表示的字符串,以0x00表示結(jié)尾,所以沒有辦法正確的存儲(chǔ)此類數(shù)據(jù),此時(shí)只能用wchar_t來保存。
UTF8編碼方式如下:用1~6個(gè)字節(jié)存儲(chǔ)一個(gè)字符,當(dāng)?shù)谝粋€(gè)字節(jié)的首位為0時(shí),表示這個(gè)字符只用一個(gè)字節(jié)表示(剛好與ASCII碼一一對(duì)應(yīng)),當(dāng)用多字節(jié)表示一個(gè)字符時(shí),首字節(jié)以連續(xù)的多個(gè)1和一個(gè)0開始,表示用多個(gè)字節(jié)。例如用3個(gè)字節(jié)是,首字節(jié)為1110xxxx,后面各字節(jié)均以10開始。
UNICODE原碼(16進(jìn)制) UTF8(2進(jìn)制)
0000-007F 0xxxxxxx
0080-07FF 110xxxxx 10xxxxxx
0800-FFFF 1110xxxx 10xxxxxx 10xxxxxx
……
如上所示,UTF8中的‘x’就是實(shí)際表示字符編碼的位。表示的最大值就是全1的情況,最小值就是少一個(gè)字節(jié)的情況下最大值加1,因?yàn)樯僖粋€(gè)字節(jié)已經(jīng)可以存的下的字符,不會(huì)用多一個(gè)字節(jié)來保存。由上可知,UTF8可以直接用char類型的字符串來表示,只是用對(duì)應(yīng)的解釋方式來解釋就可以正確顯示了。
另外一種就是GBK等編碼方式。這一類編碼方式和UNICODE沒有任何關(guān)系,是另一種字符集和編碼方式的規(guī)定。使用方法可以類比于UTF8,在編碼小于128時(shí),就是ASCII,而中文的編碼均大于128,用超過一個(gè)字節(jié)來表示。在平時(shí)編寫的windows程序中,可以理解為如果使用了UNICODE宏,就是在用wchar_t來表示中文,使用UTF16編碼,如果沒有UNICODE宏,那么就是在用GBK,以char來表示中文。
windows平臺(tái)下的TCHAR類型就是通過宏對(duì)char和wchar_t的封裝??筛鶕?jù)當(dāng)前平臺(tái)情況選擇對(duì)應(yīng)的類型。_T修飾的字符串常量同理,根據(jù)是否定義的UNICODE宏,分別表示”“或L”“。
Linux平臺(tái)的不同在于,wchar_t用4個(gè)字節(jié)表示,也就是UCS-4,而windows用兩個(gè)字節(jié),UCS-2。