C ++ wchar_t和wstrings有什么“错误”?什么是宽字符的一些替代品?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (36)

我见过很多C ++社区的人(尤其是freenode上的## c ++),他们反感使用wstringswchar_t,以及他们在windows api中的使用。究竟是什么“错误”有wchar_twstring,如果我要支持国际化,有一些什么替代宽字符?

提问于
用户回答回答于

什么是wchar_t?

定义wchar_t以便任何区域设置的char编码都可以转换为wchar_t表示,其中每个wchar_t只表示一个代码点:

类型wchar_t是一种不同的类型,其值可以表示支持的语言环境(22.3.1)中指定的最大扩展字符集的所有成员的不同代码。 - C ++ [basic.fundamental] 3.9.1 / 5

并不要求wchar_t足够大,可以同时表示来自所有语言环境的任何字符。也就是说,用于wchar_t的编码可能在语言环境中有所不同。这意味着您不一定要使用一个语言环境将字符串转换为wchar_t,然后使用其他语言环境转换回char。1

由于使用wchar_t作为所有语言环境之间的通用表示法似乎是wchar_t在实践中的主要用途,所以您可能想知道如果不是这样的话,它有什么用处。

wchar_t今天有什么用处?

无论如何,对于便携式代码来说并不多。如果__STDC_ISO_10646__已定义,则wchar_t的值直接表示在所有语言环境中具有相同值的Unicode代码点。这样可以安全地执行前面提到的区域间转换。然而,你不能仅仅依靠它来决定你可以这样使用wchar_t,因为尽管大多数unix平台定义了它,但Windows并没有在所有语言环境中使用相同的wchar_t语言环境。

Windows没有定义的原因__STDC_ISO_10646__是因为Windows使用UTF-16作为其wchar_t编码,并且因为UTF-16使用代理对来表示大于U + FFFF的代码点,这意味着UTF-16不满足要求__STDC_ISO_10646__

备择方案

我喜欢的选择是使用UTF-8编码的C字符串,即使在对UTF-8不太友好的平台上也是如此。

通过这种方式,可以使用跨平台的通用文本表示形式编写可移植代码,使用标准数据类型实现其预期用途,获得语言对这些类型的支持(例如,字符串文字,尽管一些技巧有必要使其适用于某些编译器),但有些标准库支持,调试器支持(可能需要更多技巧)等。对于宽字符,通常难以或不可能完成所有这些,并且您可能在不同的平台上获得不同的部分。

避免的替代方法

TCHAR:TCHAR是用于迁移古代Windows程序的,它假设从char到wchar_t的遗留编码,并且最好忘记,除非您的程序是在过去的千年中编写的。它不具有可移植性,对其编码甚至其数据类型本身并不具体,因此无法使用任何非基于TCHAR的API。由于它的目的是迁移到wchar_t,我们上面看到的并不是一个好主意,所以使用TCHAR没有任何价值。

1.可以在wchar_t字符串中表示但在任何语言环境中不受支持的字符不需要用单个wchar_t值表示。这意味着wchar_t可以对某些字符使用可变宽度编码,这又明显违反了wchar_t的意图。尽管wchar_t可表示的字符足以说明语言环境'支持'该字符,在这种情况下,可变宽度编码不合法,并且Window对UTF-16的使用不符合规定。

2. Unicode允许用多个代码点表示许多字符,这为简单文本算法创建与可变宽度编码相同的问题。即使严格维护一个合成规范化,某些字符仍然需要多个代码点。请参阅:http//www.unicode.org/standard/where/

用户回答回答于

这是“Unicode”上最好的引擎之一(独立于这个问题,独立于C ++)我见过:我强烈推荐它:

我真的相信,处理“8位ASCII”与“Win32宽字符”与“wchar_t-in-general”最好的方式就是接受“Windows是不同的”......并相应地编码。

我完全同意上面的jamesdlin:

在Windows上,你并没有真正的选择。它的内部API是针对UCS-2而设计的,这在自变形长度UTF-8和UTF-16编码标准化之前就已经合理了。但是现在他们支持UTF-16,他们已经结束了两个世界中最糟糕的事情。

扫码关注云+社区

领取腾讯云代金券