學習 unicode 也有一段時間了,雖然說沒有學得很好,但是卻是學到了許多東西啊,所以稍微小結一下,免得忘了,呵呵。很早就接觸過 unicode 這個詞了。不過以前太天真了,以為 unicode 是一件非常簡單的事情,很容易就解決了。只要用 TCHAR 代替 CHAR ,在所有的字符串前面加上 TEXT ,然后在 vc 里面 Preprocessor definitions 加上 _UNICODE , UNICODE 就 OK 了。實際上,僅僅這樣,還有很多疑惑不能解決。
1、 Windows XP 完全使用 unicode 開發,那為什么在 xp 下還會有亂碼呢?
內碼的存在,內碼不兼容 unicode 。或者要解釋的不是unicode,而當前不支持該編碼。
2、 為什么有 UTF-8 、 16 、 32 ?為什么說 UTF-8 是 unicode 的呢? unicode 不都是 16 位的嗎?
為了兼容現在的編碼。
3、 codepage 是什么東西?為什么存在?
4、 什么是國際化、本地化?為什么國際化、本地化那么困難?
Locale 。舉個簡單的例子:不同地方的日期的顯示格式不同。
5、 DBCS 是什么咚咚?它與 UTF-8 , unicode 有什么聯系?
UTF-8 是屬于 unicode 規范的,而 DBCS 不是。 UTF-8 是不定字節的(從一字節到六字節),而 DBCS 是雙字節的。 DBCS 與 ASCII 同時存在來處理遠東的一些字符(結合 codepage 來使用, GBK 與 Big5 的 range 就有交錯的),而 UTF-8 是 unicode 規范的實現,它包含了所有的字符。從 Windows2K 開始,從 Windows 系統的底層實現,已經全面基于 Unicode ,同時仍保證完全兼容 ANSI/DBCS 程序。
以下是對我這一階段學習的小結:
一、
????????????????????
什么是
unicode
?
Unicode provides a unique number for every character,
no matter what the platform,
no matter what the program,
no matter what the language.
歷史上有兩個組織想獨立創立單一字符集,一個是國際標準化組織( ISO )的 ISO 10646 ,另一個是由很多大企業( Apple 、 Compaq 、 HP 、 IBM 、 Microsoft 、 Oracle 等)組成的協會組織的 unicode 。 1991 年前后,他們合并了雙方的工作,統一了編碼表。雖然這兩個組織都還獨立的存在,但是他們的標準是兼容的。
Unicode 協會公布的 Unicode 標準嚴密地包含了 ISO 10646-1 實現級別 3 的基本多語言面。在兩個標準里所有的字符都在相同的位置并且有相同的名字。
Unicode
標準額外定義了許多與字符有關的語義符號學,一般而言是對于實現高質量的印刷出版系統的更好的參考。
Unicode
詳細說明了繪制某些語言
(
比如阿拉伯語
)
表達形式的算法,處理雙向文字
(
比如拉丁與希伯來文混合文字
)
的算法和排序與字符串比較所需的算法,以及其他許多東西。
另一方面 , ISO 10646 標準 , 就象廣為人知的 ISO 8859 標準一樣 , 只不過是一個簡單的字符集表 . 它指定了一些與標準有關的術語 , 定義了一些編碼的別名 , 并包括了規范說明 , 指定了怎樣使用 UCS 連接其他 ISO 標準的實現 , 比如 ISO 6429 和 ISO 2022. 還有一些與 ISO 緊密相關的 , 比如 ISO 14651 是關于 UCS 字符串排序的 .
考慮到 Unicode 標準有一個易記的名字 , 且在任何好的書店里的 Addison-Wesley 里有 , 只花費 ISO 版本的一小部分 , 且包括更多的輔助信息 , 因而它成為使用廣泛得多的參考也就不足為奇了 .
二、 ???????????????????? UTF-8 、 16 、 32
UTF : Unicode Transformation Format
首先
UCS
(
Unicode Char Set
)和
Unicode
只是分配整數給字符的編碼表
.
現在存在好幾種將一串字符表示為一串字節的方法
.
最顯而易見的兩種方法是將
Unicode
文本存儲為
2
個
或
4
個字節序列的串
.
這兩種方法的正式名稱分別為
UCS-2
(
UTF-16
)和
UCS-4
(
UTF-32
)
.
除非另外指定
,
否則大多數的字節都是這樣的
(Bigendian convention).
將一個
ASCII
或
Latin-1
的文件轉換成
UCS-2
只需簡單地在每個
ASCII
字節前插入
0x00.
如果要轉換成
UCS-4,
則必須在每個
ASCII
字節前插入三個
0x00.
在
Unix
下使用
UCS-2 (
或
UCS-4)
會導致非常嚴重的問題
.
用這些編碼的字符串會包含一些特殊的字符
,
比如
'\0'
或
'/',
它們在
文件名和其他
C
庫函數參數里都有特別的含義
.
另外
,
大多數使用
ASCII
文件的
UNIX
下的工具
,
如果不進行重大修改是無法讀取
16
位的字符的
.
基于這些原因
,
在文件名
,
文本文件
,
環境變量等地方
, UCS-2
不適合作為
Unicode
的外部編碼
.
在 ISO 10646-1 Annex R 和 RFC 2279 里定義的 UTF-8 編碼沒有這些問題 . 它是在 Unix 風格的操作系統下使用 Unicode 的明顯的方法 .
UTF-8 看起來不像是 unicode ,它只是作為一種過渡形態存在,作為新舊編碼之間交互的橋梁。雖然它是遵循 unicode 規范的,但它更像是 DBCS 的改善版,是一種 MBCS ( multi-byte char set )。顯然這個世界上不可能很快就完全 unicode , UTF-8 還將會一直存在下去。 Window NT 操作系統的基本文本表示是 UTF-16 , WCHAR 是其基本數據類型。
UTF-8 以字節為編碼單元,沒有字節序的問題。 UTF-16 以兩個字節為編碼單元,在解釋一個 UTF-16 文本前,首先要弄清楚每個編碼單元的字節序。 Unicode 規范使用 BOM ( Byte Order Mark )來標記字節順序。在 UCS 編碼中有一個叫做“ ZERO WIDTH NO-BREAK SPACE ”的字符,它的編碼是 FEFF 。而 FFFE 在 UCS 中是不存在的字符。所以,如果接收到 FEFF 就表明這個字節流是 Big-Endian 的;如果是 FFFE 則是 little endian 。 UTF-8 不需要用 BOM 來表明字節序,但可以用 BOM 來表明編碼方式。 FEFF 的 UTF-8 編碼是 EF BB BF 。
以下就是
UTF-8
的模板
0x0000 - 0x007F
用一個字節表示
0xxxxxxx
0x0080 - 0x07FF
用兩個字節表示
110xxxxx 10xxxxxx
0x0800 - 0xFFFF
用三個字節表示
1110xxxx 10xxxxxx 10xxxxxx
舉個例子,如果你遇到了 11100110 10110001 10001001 01000001 這樣的字節流,首先你看第一個字節以 1110 開頭,即讀 3 個字節并按模板提取得到 0110 110001 001001( 去除模板標志﹐再四字節四字節讀即 0x6c49) ,查 unicode 編碼表就是 " 漢 " 字 , 而最后一個以 0 開頭就一定是一個字節了, 0x0041 ,也就是 "A" 。
三、 ???????????????????? 字符集、字符編碼、內碼
字符必須編碼后才能被計算機處理。計算機使用的缺省編碼方式就是計算機的內碼。像 ASCII 、 GB2312 、 Big5 都是屬于字符編碼。當然 UTF-8 、 16 也是一種字符編碼。而 unicode 則是一種規范。
GB2312 是大陸的字符編碼標準,屬于國家標準。它是與 ASCII 碼兼容的。后來又有 GBK1.0 、 GB18030 等字符編碼標準,這些都是向下兼容的,但橫向不兼容!比如 GB2312 與 Big5 在很多編碼上是重疊的,是不兼容的; Unicode 與 GB 標準碼也是不兼容的。中文操作系統的內碼是 GBK 編碼。
由于現有的大量程序和文檔都采用樂某種特定語言的編碼,例如 GBK , windows 不可能不支持現有代碼,而全部采用 unicode !這就是為什么 windows 使用了內碼機制。為了支持更多的地方語言文字, windows 還使用了 code page 機制以使 windows 能夠更方便的適應不同地方的語言文字。 GBK 對應的 code page 是 CP936 , windows 代碼頁只支持單字節和雙字節編碼的。
GB2312-80 ,是中國大陸使用的國家標準,其中一共編碼了 6763 個常用簡體漢字。 Big5 ,是臺灣使用的編碼標準,編碼了中國臺灣使用的繁體漢字,大概有 8 千多個。 HKSCS ,是中國香港使用的編碼標準,字體也是繁體,但跟 Big5 有所不同。
四、 ???????????????????? VC 中的 Unicode 編程
這個網上的資料有很多的,最重要的一個概念就是 T , W , _UNICODE 、 UNICODE 等。這個理解起來感覺簡單很多,因為只要你在程序中都使用 Unicode 就好了。數據的傳輸、數據的保存、數據的使用、轉化都使用 Unicode (目前基本上都是使用 UTF-8 比較多吧)。當然了,這里肯定還是會有編碼格式轉化的問題的,比如輸入的不是 Unicode ,輸出的不能是 Unicode 等。但只要你在程序中都使用 Unicode 就解決問題了。是不是我想得太簡單了?
上面這些東西,很多是我從網上摘抄下來的,也有少部分是我自己的理解。如果有什么不對的地方,敬請指教。如果有什么講的不清楚的、或者需要講一下的,請提出來。如果有什么希望能夠一起討論討論的,歡迎給我發郵件或回帖討論!