Unicode在C + + 11
我一直在阅读Unicode的主题 – 特别是在C ++ 11中的UTF-8(非)支持,我希望Stack Overflow的专家能够向我保证我的理解是正确的,或者指出我误解的地方或错过的地方。
一个简短的总结
首先,你可以在源代码中定义UTF-8,UTF-16和UCS-4文字。 此外, <locale>
头文件包含了几个可以在UTF-8,UTF-16,UCS-4和平台多字节编码之间进行转换的std::codecvt
实现(尽pipeAPI看起来很温和,但小于直截了当)。 这些codecvt
实现可以imbue()
在stream上,以便在读取或写入文件(或其他stream)时进行转换。
[ 编辑: Cubbi指出,我忽略了提及<codecvt>
标题,它提供了不依赖于语言环境的std::codecvt
实现。 此外, std::wstring_convert
和wbuffer_convert
函数可以使用这些codecvt
来直接转换string和缓冲区,而不依赖于stream。]
C ++ 11还包括C99 / C11 <uchar.h>
头文件,其中包含将平台多字节编码(可能是也可能不是UTF-8)的单个字符转换成UCS-2和UCS-4的函数。
但是,这是关于它的程度。 虽然你当然可以将UTF-8文本存储在std::string
,但是我没有办法看到对它做任何有用的事情。 例如,除了在你的代码中定义一个文字,你不能validation一个字节数组是否包含有效的UTF-8,你不能找出长度(即Unicode字符的数量,对于“字符” )包含一个UTF-8的std::string
,并且不能以字节为单位以任何方式迭代std::string
。
同样,即使C ++ 11增加了std::u16string
也不是真的支持UTF-16,而只是老的UCS-2 – 它不支持代理对,只留下了BMP。
意见
鉴于UTF-8是几乎所有Unix派生系统(包括Mac OS X和 * Linux)上处理Unicode的标准方法,并且已经基本成为网上事实上的标准,所以在现代C ++中缺乏支持像一个非常严重的遗漏。 即使在Windows上,新的std::u16string
并不真正支持UTF-16的事实似乎有些遗憾。
*正如在评论中指出的,在这里明确指出,Mac OS的BSD派生部分使用UTF-8,而Cocoa使用UTF-16。
问题
如果您设法阅读所有这些,谢谢! 只是几个简单的问题,因为这是堆栈溢出毕竟…
-
上面的分析是否正确,或者是否有其他Unicode支持设施?
-
在过去几年中,标准委员会在推动C ++向前发展方面做了出色的工作。 他们都是聪明的人,我认为他们很清楚上述缺点。 是否有一个众所周知的原因,Unicode支持在C ++中仍然很差?
-
outlook未来,有没有人知道有什么scheme可以纠正? 快速searchisocpp.org似乎没有透露任何东西。
编辑:谢谢大家的回应。 我不得不承认,我觉得它们有点令人沮丧 – 在不久的将来,现状似乎不太可能改变。 如果在认知方面有一个共识,那么似乎完全的Unicode支持太难了,任何解决scheme都必须重新实现大多数ICU才能被认为是有用的。
我个人不同意这个; 我觉得有宝贵的中间地带可以find。 例如,UTF-8和UTF-16的validation和规范化algorithm由Unicode联盟明确规定,并且可以由标准库作为自由函数在std::unicode
命名空间中提供。 对于那些需要与需要Unicodeinput的库进行交互的C ++程序来说,这些将会非常有帮助。 但是根据下面的答案(必须说,有一点苦涩),似乎Puppy对这种有限的function的build议并没有得到很好的回应。
上述分析是否正确?
让我们来看看。
您不能validation包含有效UTF-8的字节数组
不正确。 std::codecvt_utf8<char32_t>::length(start, end, max_lenght)
返回数组中的有效字节数。
你找不到长度
部分正确。 可以转换为char32_t并找出结果的长度。 没有简单的方法找出长度,而没有做实际的转换(但见下文)。 我必须说,需要统计字符(从任何意义上说)都是很less出现的。
您不能以字节为单位以任何方式迭代std :: string
不正确。 std::codecvt_utf8<char32_t>::length(start, end, 1)
为您提供了遍历UTF-8“字符”(Unicode代码单元)的可能性,当然还要确定它们的数量(这不是一个“简单”的方法来计算字符的数量,但这是一种方式)。
并不真正支持UTF-16
不正确。 可以使用std::codecvt_utf8_utf16<char16_t>
转换UTF-16和UTF-16。 转换为UTF-16的结果就是UTF-16。 它不限于BMP。
演示说明这些要点 。
如果我错过了其他的“你不能”,请指出来,我会解决它。
上面的分析是否正确,或者是否有其他Unicode支持设施?
你也错过了UTF-8文字的完全失败。 他们没有一个明确的字符types,可能有一个完全不相关的(例如代码页)编码。 因此,他们不但没有在C ++ 11中添加任何严重的新function,而且打破了原来的一点,因为现在你甚至不能假设你的平台的string是窄字符编码的,除非UTF-8是窄string编码。 所以这里的新function是“我们完全打破了UTF-8不是现有的窄string编码的每个平台上基于string的string”。
在过去几年中,标准委员会在推动C ++向前发展方面做了出色的工作。 他们都是聪明的人,我认为他们很清楚上述缺点。 是否有一个众所周知的原因,Unicode支持在C ++中仍然很差?
委员会似乎没有提到Unicode的问题。
另外,许多Unicode支持algorithm就是这些algorithm。 这意味着要提供一个体面的界面,我们需要范围。 我们都知道,委员会无法弄清楚他们想要的范围。 埃里克·尼布勒(Eric Niebler)提出的新的“无敌”
outlook未来,有没有人知道有什么scheme可以纠正? 快速searchisocpp.org似乎没有透露任何东西。
有N3572,我写的。 但是当我去布里斯托尔并提交时,出现了一些问题。
首先,事实certificate,委员会不会在会议之间反馈非委员会成员提出的提案,导致在迭代不需要的devise时会导致数月的工作失败。
第二,事实certificate,当时谁是偶然溜走呢? 这意味着,如果你的论文被重新安排,你会有一些相对随机的人,他们可能会或可能不知道任何关于主题的内容。 或者甚至什么都没有。
第三,由于某种原因,他们似乎并不认为目前的情况是一个严重的问题。 你可以得到无尽的讨论,究竟应该如何定义optional<T>
比较操作,但处理用户input ? 谁在乎呢?
第四,每篇论文都需要一个冠军来有效地呈现和维护它。 考虑到以前的问题以及我无法前往其他会议的事实,那肯定不会是我,今后不会是我,除非你想捐出所有的旅费和工资最重要的是,没有其他人似乎在乎足够的努力。