確定Windows XP到底是UCS-2的還是UTF-16的

來源:互聯網
上載者:User

一般認為Windows下以16bit表示的Unicode並不是UTF-16,而是UCS-2。UCS-2是一種編碼格式,同時也是指以一一對應關係的Unicode實現。在UCS-2中只能表示U+0000到U+FFFF的BMP(Basic Multilingual Plane ) Unicode編碼範圍,屬於定長的Unicode實現,而UTF-16是變長的,類似於UTF-8的實現,但是由於其位元組長度的增加,所以BMP部分也做到了一一對應,但是其通過兩個雙位元組的組合可以做到表示全部Unicode,表示範圍從U+0000 到 U+10FFFF。關於這一點,我在很多地方都看到混淆了,混的我自己都有點不太肯定自己的說法了,還好在《UTF-16/UCS-2》中還是區別開了,不然我不知道從哪裡去尋找一個正確答案。(哪怕在IBM的相關網頁上都將UCS-2作為UTF-16的別名列出)

在《UTF-16/UCS-2》文中有以下內容:

UTF-16 is the native internal representation of text in the Microsoft Windows 2000/XP/2003/Vista/CE; Qualcomm BREW operating systems; the Java and .NET bytecode environments; Mac OS X's Cocoa and Core Foundation frameworks; and the Qt cross-platform graphical widget toolkit.[1][2][citation needed]

Symbian OS used in Nokia S60 handsets and Sony Ericsson UIQ handsets uses UCS-2.

The Joliet file system, used in CD-ROM media, encodes filenames using UCS-2BE (up to 64 Unicode characters per file).

Older Windows NT systems (prior to Windows 2000) only support UCS-2.[3]. In Windows XP, no code point above U+FFFF is included in any font delivered with Windows for European languages, possibly with Chinese Windows versions.[clarification needed]

很明確的說明了Windows 2000以後核心已經是UTF-16的了,這點還真是與平時的感覺相違背,於是可以測試一下。在UTF-16的編碼轉換函式(Python實現)

中我在windows下輸出了三個太玄經的字元,“”不過實際實在UltraEdit中輸出的,雖然在windows下的確是顯示出來了,但是也可能是UltraEdit的功能,我們這次用windowsAPI顯示出來,以此證明,Windows的核心的確是能夠識別並顯示此三個太玄經的字元。至於為什麼能顯示太玄經的字元就表示核心是UTF-16的,是因為UCS-2隻能表示到BMP範圍的字元,太玄經的字元超出了其能表示的範圍,假如你有古老電腦的,安裝著Windows NT早期版本的系統,可以用同樣的例子試試,應該是不能顯示出來的。

int _tmain(int argc, _TCHAR* argv[])

{

wchar_t lwc[8];

lwc[0] = 0xd834;

lwc[1] = 0xdf00;

lwc[2] = 0xd834;

lwc[3] = 0xdf01;

lwc[4] = 0xd834;

lwc[5] = 0xdf02;

lwc[6] = 0;

lwc[7] = 0;

MessageBoxW(NULL, lwc, lwc, MB_OK);

return 0;

}

會彈出一個對話方塊,顯示字元。很顯然,Windows核心是能正確識別UTF-16字元了。

但是為什麼平時都說Windows是UCS-2的呢?因為其編程的介面都是UCS-2的,根本不能理解超出UCS-2但是確是UTF-16的字元,比如上述的太玄經字元。在上面的例子中,其實只有3個字元,顯示的時候也能正確,但是看下面的例子:

int _tmain(int argc, _TCHAR* argv[])

{

wchar_t lwc[8];

lwc[0] = 0xd834;

lwc[1] = 0xdf00;

lwc[2] = 0xd834;

lwc[3] = 0xdf01;

lwc[4] = 0xd834;

lwc[5] = 0xdf02;

lwc[6] = 0;

lwc[7] = 0;

int i = wcslen(lwc);

printf("%d\n", i);

int j = lstrlenW(lwc);

printf("%d\n", j);

return 0;

}

無論是i,j都是6,也就是說,無論是Windows下的C語言庫函數(wcslen),還是其API(lstrlenW是windows的API,這點不要奇怪),都是無法正確識別UTF-16字元的,連數數都不會數,所以實際的編程體驗就是,雖然其核心UTF-16化了,但是你還是只能當UCS-2來使用-_-!

以上測試也許還不能完全讓人信服,再看看MFC的例子(VS2005下的MFC版本)

老地方 http://groups.google.com/group/jiutianfile/

有一個TestUnicodeMFc.rar的工程,開啟看看,就知道了。當太玄經的3個字元在輸入框中時,通過CEdit控制項計算出來的長度是6,最最與以前多位元組的時候想的是,當你刪除一個字元(按一下backspace),你刪除的不是一個太玄經字元,而是刪除了最後一個字元的一半,然後最後一個字元雖然消失了,但是你發現還有其一半的存在,然後計算長度,輸出的是5。唯一比以前好的是,沒有出現亂碼,原因在於,這個單個的UTF-16字元已經超過了UCS-2能表示的範圍,所以沒有意義。

至此,我的結論是,Windows是已經從核心支援UTF-16了,但是你還是得在UCS-2上編程-_-!

關於此部分內容參看《UTF-16/UCS-2》。

關於Unicode的編碼範圍的內容參看《Mapping of Unicode character planes》。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.