char vs wchar_t vs char16_t vs char32_t(c ++ 11)

use*_*963 46 c++ c++11

根据我的理解,a char是安全的容纳ASCII字符,char16_t而且char32_t可以安全地容纳来自unicode的字符,一个用于16位变体,另一个用于32位变量(我应该说"a"而不是"the" ?).但我当时想知道背后的目的wchar_t是什么.我应该在新代码中使用该类型,还是仅仅支持旧代码?wchar_t如果根据我的理解,它的大小不能保证大于一个,那么旧代码的目的是什么char?澄清会很好!

bam*_*s53 54

char用于8位代码单元,char16_t用于16位代码单元,char32_t用于32位代码单元.其中任何一个都可以用于'Unicode'; UTF-8使用8位代码单元,UTF-16使用16位代码单元,UTF-32使用32位代码单元.


所做的保证wchar_t是,语言环境中支持的任何字符都可以转换charwchar_t,并且无论使用什么表示char,可以是多个字节,移位代码,有什么东西,wchar_t它将是单个不同的值.这样做的目的是,您可以wchar_t像使用ASCII的简单算法一样操纵字符串.

例如,将ascii转换为大写如下:

auto loc = std::locale("");

char s[] = "hello";
for (char &c : s) {
  c = toupper(c, loc);
}
Run Code Online (Sandbox Code Playgroud)

但是这不会处理将UTF-8中的所有字符转换为大写,或者转换为其他一些编码(如Shift-JIS)中的所有字符.人们希望能够像这样将这些代码国际化:

auto loc = std::locale("");

wchar_t s[] = L"hello";
for (wchar_t &c : s) {
  c = toupper(c, loc);
}
Run Code Online (Sandbox Code Playgroud)

所以每个wchar_t都是一个'字符',如果它有一个大写版本,那么它可以直接转换.不幸的是,这并不是真的有效; 例如,在某些语言中存在奇怪之处,例如德语字母ß,其中大写版本实际上是两个字符SS而不是单个字符.

因此,国际化的文本处理本质上比ASCII更难,并且不能像设计者那样真正简化wchar_t.因此wchar_t,广泛的字符一般提供的价值很小.

使用它们的唯一原因是它们已被烘焙到一些API和平台中.但是,我更喜欢在我自己的代码中坚持使用UTF-8,即使在这样的平台上进行开发,也只是在API边界转换为所需的编码.

  • 我喜欢你的评论和Kuhl的评论,他们都有独特的信息.我希望我可以给两张绿色支票.我将不得不考虑决定谁得到它.stackoverflow上的标准协议是否在没有关系的情况下不进行检查? (2认同)
  • @IInspectable 使用“SS”不是 Unicode 大小写算法的发明。以实际使用为准。使用“SS”和“SZ”已成为常见做法,Unicode 算法旨在尊重这一点。从 Unicode 文档中,您链接到“特别是,大写尖 s 旨在用于标牌和大写标题的印刷表示,以及用户需要将尖 s 保留为大写的其他环境。**总的来说,这种用法很少见** .” (2认同)
  • ß传统上没有大写字母,因为它不是字母,而是传统小写字母(在fraktur中写成垂直条)和小写字母z的连字.这就是所谓的esszet是德语.Unicode 5.1引入的大写"ẞ"仅适用于标题套管.实际文本中的大写字母不得使用它. (2认同)

Die*_*ühl 20

wchar_t当Unicode承诺创建16位表示时,该类型被置于标准中.大多数供应商选择制造wchar_t32位,但一家大型供应商选择将其制作为16位.由于Unicode使用超过16位(例如,20位),因此我们觉得我们应该有更好的字符类型.

意图char16_t是表示UTF16并且char32_t意味着直接表示Unicode字符.但是,在使用wchar_t作为基本界面一部分的系统上,您将被困在wchar_t.如果你不受约束,我个人会char用UTF8代表Unicode.这个问题char16_tchar32_t是它们不完全支持,甚至没有在标准C++库:比如,没有直接支持这些类型的流,它不仅仅是实例为这些类型的流更多的工作.