學習
unicode
也有一段時間了,雖然說沒有學得很好,但是卻是學到了許多東西啊,所以稍微小結一下,免得忘了,呵呵。很早就接觸過
unicode
這個詞了。不過以前太天真了,以為
unicode
是一件非常簡單的事情,很容易就解決了。只要用
TCHAR
代替
CHAR
,在所有的字符串前面加上
TEXT
,然后在
vc
里面
Preprocessor definitions
加上
_UNICODE
,
UNICODE
就
OK
了。實際上,僅僅這樣,還有很多疑惑不能解決。
1、
Windows XP
完全使用
unicode
開發,那為什么在
xp
下還會有亂碼呢?
內碼的存在,內碼不兼容
unicode
?;蛘咭忉尩牟皇莡nicode,而當前不支持該編碼。
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
就解決問題了。是不是我想得太簡單了?
?
上面這些東西,很多是我從網上摘抄下來的,也有少部分是我自己的理解。如果有什么不對的地方,敬請指教。如果有什么講的不清楚的、或者需要講一下的,請提出來。如果有什么希望能夠一起討論討論的,歡迎給我發郵件或回帖討論!