wchar_t 的長度…

| 7/02/2010
wchar_t 是 ANCI C 提供支援 Unicode 的方案。使用方式跟一般 char * 字串很像,整個介面都是差不多的。

char * anciStr = "測試"
wchar_t * uniStr = L"測試" // 注意這裡需要加上一個 micro

而我們常用的字串函式 strlen, strcpy 等,自然就會有對應的東西出現:wcslen, wcscpy。這些東西則是定義再 wchar.h 裡面。

雖然支援了 Unicode 是很好,但是並不是所有的作業系統對這些東西的編碼定義都相同。今天如果要做跨平台的系統程式設計,就得要不斷的面對每個系統對字元符號的編碼定義不同的問題。好比如說,在 Windows 上面, char 字元預設是 ASCII +1 的 8bit 字,wchar_t 則是 UTF-16 Little Endian。這看起來像是很合情合理,但是像是 Linux、Mac OS X 這種全面支援 Unicode 的系統而言,char 早就已經是 Unicode 了。同樣是 Unicode ,卻依然有大大的不同!在這兩的系統上面,char 是被定義成 UTF-8(今天 Windows 在 UTF-8 上面是有 BOM 的,而這裡沒有。其實 BOM 對 UTF-8 而言很沒意義),而 wchar_t 則是 UTF-32(Big Endian 跟 Little Endian 都有可能,看 CPU)。所以說,我們用函式測試的時候就會出現這樣的結果:

strlen(anciStr) // Windows 會出現 4,Linux、Mac 則是 6
wcslen(uniStr) // 這裡統一會出現 2
看的懂差異的來源嗎?

今天 Cocoa Foundation 提供 NSString 的 Class,這個 Class 是以 UTF-16 Big Endian 儲存的。但是該 Class 本身具備好了許多編碼轉換的函式,可以讓你在 不同的編碼之間轉換!所以說,NSString 跟 wchar_t 之間的變化,應該是:

wchar_t * string = malloc([nsString length] * sizeof(wchar_t) + 1);
wcscpy(string, (const wchar_t *)[nsString cStringUsingEncoding:NSUTF32LittleEndianStringEncoding]);

沒有留言: