C ++ 11中的Unicode

特里斯坦·布林德尔:

我一直在阅读一些有关Unicode的主题-特别是UTF-8-C ++ 11中的(非)支持,我希望Stack Overflow上的专家可以使我确信我的理解是正确的,或者指出在这种情况下我误解或错过的地方。

简短摘要

首先,优点:您可以在源代码中定义UTF-8,UTF-16和UCS-4文字。此外,<locale>标头包含几种std::codecvt实现,可以在UTF-8,UTF-16,UCS-4和平台多字节编码之间进行转换(尽管API似乎有点不那么简单)。这些codecvt实现可以imbue()在流上进行,以允许您在读取或写入文件(或其他流)时进行转换。

[ 编辑: Cubbi在我忽略的评论中指出了<codecvt>标头,该标头提供了std::codecvt不依赖于语言环境的实现。另外,std::wstring_convertand wbuffer_convert函数可以使用这些codecvt来直接转换字符串和缓冲区,而不依赖于流。

C ++ 11还包括C99 / C11 <uchar.h>标头,该标头包含用于将各个字符从平台多字节编码(可能为UTF-8,也可能不是UTF-8)转换为UCS-2和UCS-4的功能。

但是,这只是它的程度。当然,您可以将UTF-8文本存储在中std::string,但我看不出有什么方法可以对它做任何真正有用的事情。例如,除了在代码中定义文字之外,您无法验证字节数组包含有效的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的标准方法, 并且在很大程度上已成为Web上的事实上的标准,因此现代C ++似乎缺乏支持就像一个非常严重的遗漏。即使在Windows上,新设备std::u16string也不真正支持UTF-16 的事实似乎有些令人遗憾。

*如评论中指出并在此处明确指出的那样,Mac OS的BSD衍生部分使用UTF-8,而Cocoa使用UTF-16。

问题

如果您能阅读所有内容,谢谢!只是几个简单的问题,因为毕竟这是堆栈溢出...

  • 以上分析是否正确,或者我还缺少其他任何支持Unicode的功能?

  • 在过去的几年中,标准委员会做了出色的工作,使C ++迅速发展。他们都是聪明人,我想他们已经清楚上述缺点。在C ++中,对Unicode的支持仍然很差吗?

  • 展望未来,有人知道任何纠正情况的建议吗?在isocpp.org上进行的快速搜索似乎没有发现任何内容。

编辑:谢谢大家的答复。我不得不承认,我发现他们有些令人沮丧-看起来现状在不久的将来不太可能改变。如果在cognoscenti之间达成共识,似乎完全的Unicode支持太难了,任何解决方案都必须重新实现大多数ICU,才被认为有用。

我个人不同意。我认为可以找到有价值的中间立场。例如,UTF-8和UTF-16的验证和规范化算法由Unicode联盟很好地指定,并且可以由标准库作为例如std::unicode名称空间中的自由函数提供对于需要与需要Unicode输入的库进行接口的C ++程序而言,仅这些一项就可以提供很大的帮助。但是基于下面的答案(一定要说出来,带着些许苦涩),似乎Puppy提出的关于这种有限功能的建议没有被很好地接受。

代词

以上分析正确吗

让我们来看看。

您无法验证字节数组包含有效的UTF-8

不正确 std::codecvt_utf8<char32_t>::length(start, end, max_lenght)返回数组中有效字节的数量。

你找不到长度

部分正确。可以将其转换为char32_t并找出结果的长度。有没有简单的方法来找出没有做实际的转换长度(见下文)。我必须说(很少)计数字符的需求很少出现。

您不能以逐字节以外的任何方式遍历std :: string

不正确 std::codecvt_utf8<char32_t>::length(start, end, 1)使您可以遍历UTF-8“字符”(Unicode代码单元),并确定它们的数量(这不是计算字符数的“简便”方法,而是一种方法)。

并不真正支持UTF-16

不正确 例如,您可以使用UTF-16来回转换std::codecvt_utf8_utf16<char16_t>转换为UTF-16的结果就是UTF-16。它不限于BMP。

演示说明了这些观点

如果我错过了其他“你不能”的地方,请指出来,我会解决的。

重要附录这些功能在C ++ 17 已弃用这可能意味着它们将在将来的C ++版本中消失。使用它们需要您自担风险。现在,仅使用标准库就无法(安全地)再次完成原始问题中列举的所有这些操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章