【发布时间】:2010-12-09 11:13:47
【问题描述】:
为什么需要wchar_t?它比short(或__int16 或其他)有什么优势?
(如果重要的话:我生活在 Windows 世界中。我不知道 Linux 为支持 Unicode 做了什么。)
【问题讨论】:
为什么需要wchar_t?它比short(或__int16 或其他)有什么优势?
(如果重要的话:我生活在 Windows 世界中。我不知道 Linux 为支持 Unicode 做了什么。)
【问题讨论】:
基本上,它是当前语言环境中“文本”的可移植类型(带有变音符号)。它早于 Unicode,并没有解决很多问题,所以今天,它主要是为了向后兼容而存在的。除非必要,否则不要使用它。
【讨论】:
wchar_t 显然支持所有的 unicode 字符。 UTF-16 也是如此,尽管 BMP 集之外的字符需要 2 个 WCHAR(4 个字节)。谷歌术语:“高低代理”。对于中文/日文/韩文,UTF-16 比 UTF-8 更有效(大多数 CJK 表意文字在 UTF-8 中占用 3 个字节)
为什么需要 wchar_t?它如何优于 short(或 __int16 或其他)?
在 C++ 世界中,wchar_t 是它自己的类型(我认为它是 C 中的 typedef),因此您可以基于此重载函数。例如,这可以输出宽字符,而 not 可以输出它们的数值。在 VC6 中,wchar_t 只是 typedef 的 unsigned 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。
【讨论】:
存在wchar_t 的原因与存在size_t 或time_t 的原因几乎相同 - 它是一种抽象,指示类型要表示的内容并允许实现选择可以表示的底层类型特定平台上的正确类型。
请注意,wchar_t 不需要是 16 位类型 - 有些平台是 32 位类型。
【讨论】:
wchar_t 并且任何整数类型恰好在大小上与 @987654326 重叠@。 C 没有重载,所以不需要。
通常认为给数据类型这样的东西有意义的名字是一件好事。
什么是最好的,char 还是 int8?我认为:
char name[] = "Bob";
比这更容易理解:
int8 name[] = "Bob";
wchar_t 和 int16 也是一样的。
【讨论】:
当我阅读相关标准时,微软似乎把这个标准搞砸了很糟糕。
我的 POSIX 手册页 <stddef.h> 说:
- wchar_t:整数类型,取值范围可以 代表不同的宽字符 指定的最大字符集的所有成员的代码 编译环境支持的语言环境:null 字符的代码值为 0 并且 可移植字符集的每个成员的代码值等于 用作整数字符中的唯一字符时的值 常数。
因此,如果您的平台支持 Unicode,那么 16 位 wchar_t 是不够的。每个 wchar_t 都应该是一个字符的不同值。因此,wchar_t 从一种在文本字符级别工作的有用方式(当然,在从语言环境多字节解码之后)变成了在 Windows 平台上完全无用的方式。
【讨论】:
wchar_t 是否必须能够表示所有 Unicode 代码点,或者只是所有代码 units?在UTF16的情况下,一个代码单元是一个16位的整数,所有这些都可以用微软的wchar_t来表示。
L"blah") 在 Windows 上是 UTF-16 编码的。因此它能够表示完整的 Unicode,但它是一种多字节编码(至少对于某些 Unicode 字符而言)。 ICBWT。
wchar_t 的重点是将多字节编码解码为一个简单的表示,每个数组位置都有一个字符。 Windows 上指定的最大字符集是 Unicode。 UTF-16 不是字符集,它是 Unicode 的编码。
wchar_t 是用于存储和处理平台的 unicode 字符的原语。它的大小并不总是 16 位。在 unix 系统上,wchar_t 是 32 位的(也许 unix 用户更可能使用额外位用于的克林贡字符:-)。
这可能会给移植项目带来问题,尤其是如果您将wchar_t 和short 互换,或者如果您将wchar_t 和xerces' XMLCh 互换。
因此,将wchar_t 作为与short 不同的类型对于编写跨平台代码非常重要。清理这是将我们的应用程序移植到 unix,然后从 VC6 到 VC2005 的最困难的部分之一。
【讨论】:
wchar_t,大部分时间将文本表示为 UTF-8 :)
补充 Aaron 的评论 - 在 C++0x 中,我们终于获得了真正的 Unicode 字符类型:char16_t 和 char32_t 以及 Unicode 字符串文字。
【讨论】:
从某种意义上说,它是“高级”的,它允许您分隔上下文:您在字符上下文(如字符串)中使用wchar_t,在数字上下文(数字)中使用short。现在,编译器可以执行类型检查来帮助您捕捉错误地将一种与另一种混合在一起的情况,例如将shorts 的抽象非字符串数组传递给字符串处理函数。
作为一个边节点(因为这是一个 C 问题),在 C++ 中,wchar_t 允许您独立于 short 重载函数,即再次提供适用于字符串和数字的独立重载(例如)。
【讨论】:
wchar_t 可以独立于 short 或 int 进行重载。
wchar_t 有点像 unicode 标准化之前的遗留问题。不幸的是,它不是很有帮助,因为编码是特定于平台的(在 Solaris 上,是特定于语言环境的!),并且没有指定宽度。此外,无法保证 utf-8/16/32 编解码器方面将可用,或者您将如何访问它们。一般来说,便携式使用有点像噩梦。
显然 c++0x 将支持 unicode,但以目前的进展速度可能永远不会发生......
【讨论】:
除了一个小的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?。
【讨论】:
__STDC_ISO_10646__ 表示 wchar_t 的值与 Unicode 码位的值相同。该条件不适用于 Unicode 编码 UTF-16 和 UTF-8,但它确实适用于 ASCII 和 UCS-2。
__STDC_ISO_10646__ 说什么 wchar_t 都不应该存储 UTF-16(或任何其他编码形式),这明显违反了上面引用的 POSIX 标准。存储 UCS-2 即可。在不关心标准的平台上,所有赌注都失败了。
wchar_t API,不限于当前 C 或 C++ 语言环境支持的字符。 wctomb() 仅定义为处理语言环境支持的字符,语言环境支持的字符需要由不同的wchar_t 值表示。只要没有语言环境支持 BMP 之外的任何字符,那么技术上就不会违反标准。我不会争辩说 UTF-16 不是滥用和违反 wchar_t 的精神,只是说它在技术上并不违反规范的文字。