2009-10-23 78 views
23

爲什麼需要wchar_t?它如何優於short(或__int16或其他)?wchar_t爲什麼發明?

(如果它的事項:我住在Windows世界中,我不知道什麼是Linux確實爲支持Unicode)。

+1

相關:[wchar_t是否需要unicode支持?](http://stackoverflow.com/questions/2259544/is-wchar-t-needed-for-unicode-support) – sleske 2013-08-08 14:28:39

回答

17

爲什麼wchar_t的需要?它如何優於short(或__int16或其他)?

在C++的世界裏,wchar_t是其自己的類型(我認爲這是一個在C typedef),這樣你就可以重載基於此功能。例如,這使得有可能輸出寬字符和輸出它們的數值。在VC6,其中wchar_t只是一個typedefunsigned short,該代碼

wchar_t wch = L'A' 
std::wcout << wch; 

將輸出65因爲

std::ostream<wchar_t>::operator<<(unsigned short) 

被調用。在較新的版本的VC是wchar_t一個獨特的類型,所以

std::ostream<wchar_t>::operator<<(wchar_t) 

被調用,且其輸出A

+0

順便說一下:在新的VC的項目設置中可以禁用此行爲(您不應該但可能需要向後兼容) – mmmmmmmm 2009-10-23 19:58:52

17

Wikipedia

基本上,它是當前語言環境中的「文本」的可移植類型(帶有元音變音)。它早於Unicode,並沒有解決許多問題,所以今天,它主要是爲了向後兼容而存在的。除非必須,否則不要使用它。

+8

阿門。事實上,完全轉儲ANSI語言環境的東西。將所有文本視爲utf8(如果必須轉換爲輸入)並使用標準C庫函數。這是唯一可行的方式去做I18N在C. – 2009-10-23 15:36:08

+0

不幸的是,這並不總是奏效。對於多字節字符串,C標準庫的某些實現假定每個字符最多2個字節,並且不支持UTF-8語言環境。搜索Michael Kaplan的博客瞭解更多信息。 – 2009-10-23 16:03:12

+4

Nemanja,Michael Kaplan是一位多產作家。你可以更具體一點關於搜索什麼? – 2009-10-23 16:05:27

8

通常認爲給予數據類型有意義的名稱是件好事。

什麼是最好的,charint8?我覺得這樣的:

char name[] = "Bob"; 

更容易比這個理解:

int8 name[] = "Bob"; 

這是一個與wchar_t的INT16同樣的事情。

+0

很好的例子使它清楚。 – mmmmmmmm 2009-10-23 20:00:43

+0

但是,wchar_t的大小並不總與int16的大小相同。這是一種寬度從平臺到平臺不同的類型,不幸... – fbrereto 2009-10-23 22:50:18

+0

這就是C++ 0x引入char16_t和char32_t的原因,因此您可以明確使用UTF16或UCS4,同時仍保留字符語義。 – Porculus 2010-11-29 16:37:41

2

從某種意義上說,它是「優越的」,它允許您分開上下文:在字符上下文中使用wchar_t(如字符串),並且在數字上下文中使用short(數字)。現在,編譯器可以執行類型檢查,以幫助您捕獲錯誤地將一個文件與另一個文件混合的情況,例如將一個抽象的非字符串數組short s傳遞給字符串處理函數。

作爲一個節點(因爲這是一個C問題),在C++中wchar_t允許您獨立於short重載函數,即再次提供獨立的過載(例如,使用字符串和數字)。

+0

+1表示可以獨立於short或int來重載'wchar_t'。 – 2009-10-23 14:49:45

5

wchar_t是存儲和處理平臺unicode字符的原語。它的大小並不總是16位。在Unix系統wchar_t是32位(也許unix用戶更可能使用額外的位用於:-)克林昂charaters。

這可能會造成移植項目時出現問題,特別是如果您交換wchar_t和縮寫,或者如果您交換wchar_t和xerces'XMLCh

因此將wchar_t作爲不同的類型來縮短對編寫跨平臺代碼非常重要。清理這個是將應用程序移植到unix,然後從VC6移植到VC2005中最困難的部分之一。

+5

順便說一句,UNIX程序通常會跳過'wchar_t',很多時候代表文本爲UTF-8 :) – bdonlan 2009-10-23 14:19:17

+2

我知道如果我再次重做我們的應用程序,我會贊成utf-8 over ucs-16/utf16。 – iain 2009-10-25 17:21:02

6

在我閱讀相關標準時,看起來好像微軟在很差的

我對POSIX <stddef.h>手冊頁說:

  • wchar_t的:整型值,其範圍可 代表不同的寬字符 代碼最大的字符集的所有MEM-別爾斯間 由編譯環境支持的語言環境指定:空 字符具有代碼值0和 便攜式字符集的每個成員具有代碼值等於 它作爲一個整數的字符 恆定孤字符,用於當s值。

因此,如果您的平臺支持Unicode,16位wchar_t是不夠的。每個wchar_t應該是一個角色的獨特值。因此,wchar_t的去從一個有用的方法,在文本的角色等級達到正常工作(從區域設置多字節解碼後,當然),以作爲在Windows平臺上完全無用。

+3

我認爲這不是Microsoft的實現中的問題,而是C++規範並沒有真正考慮Unicode。什麼是Unicode中的字符集? 'wchar_t'必須能夠代表所有的Unicode代碼點,或者只能代表所有的代碼*單元*?對於UTF16,代碼單元是一個16位整數,所有這些都可以用微軟的'wchar_t'表示。 – jalf 2009-10-23 14:41:01

+2

我認爲寬字符串('L「blah」')在Windows上是UTF-16編碼。所以它能夠表示完整的Unicode,但是是一個多字節編碼(至少對於某些Unicode字符)。 ICBWT。 – sbi 2009-10-23 14:42:48

+1

如果它是一個多字節編碼,那麼它的'範圍值'不能真正爲字符集的所有成員保存不同的值,可以嗎? – gnud 2009-10-25 09:24:18

10

的原因有一個wchar_t幾乎是一樣的道理有一個size_ttime_t - 這是一個抽象表示什麼類型意在代表和允許實現選擇的基本類型,可以適當地代表了一個類型特定的平臺。

請注意,wchar_t不需要是16位類型 - 有平臺是32位類型。

+0

請注意,在C++中,wchar_t是內置類型(如char),而size_t和time_t是類型定義。 – rdb 2015-10-10 18:09:30

3

要添加到Aaron的評論 - 在C++ 0x中,我們終於得到真正的Unicode字符類型:char16_t和char32_t以及Unicode字符串文字。

2

wchar_t的是有點宿醉從Unicode標準化之前。不幸的是,它不是很有用,因爲編碼是特定於平臺的(並且在Solaris上,特定於語言環境!),寬度未指定。另外,我們不保證utf-8/16/32 codecvt facets可用,或者確實如何訪問它們。一般來說,這對於便攜式使用來說是一場噩夢。

顯然的C++ 0x將支持Unicode,但在那個可能永遠不會發生現在的速度......

1

除少量,ISO 2022 japanese minority,wchar_t的總是會是Unicode。如果你真的很着急,你可以在編譯時確保這一點:

#ifndef __STDC_ISO_10646__ 
#error "non-unicode wchar_t, unsupported system" 
#endif 

有時wchar_t的是16位UCS-2,有時32位UCS-4,還等什麼?只需使用sizeof(wchar_t)。 wchar_t不是意味着被髮送到磁盤或網絡,它只是用在內存中。

另請參見Should UTF-16 be considered harmful?在本網站上。

+0

'__STDC_ISO_10646__'表示wchar_t的值與Unicode代碼點的值相同。對於Unicode編碼UTF-16和UTF-8,該條件不適用,而對ASCII和UCS-2則爲_does_。 – bames53 2012-06-13 15:37:59

+0

無論什麼'__STDC_ISO_10646__'都表示wchar_t從不應該存儲UTF-16(也不是其他任何編碼格式),這明顯違反了上面引用的POSIX標準。存儲UCS-2即可。 在不關心標準的平臺上,所有投注都關閉。 – MarcH 2013-03-29 23:13:08

+0

它不是那麼幹燥。如果您指的是引用,表示支持的語言環境中的最大字符集中的所有字符都由不同的wchar_t值表示,這些值不排除UTF-16,超過它排除UCS-2;只要沒有語言環境支持非BMP字符,那麼如果這些非BMP字符不是由不同的wchar_t值表示的,這在技術上不是違規。當然,如果對字符的區域支持是唯一的支持,那麼您將無法區分差異,但事實並非如此。 – bames53 2013-03-30 22:12:38