Tri*_*dle 57 c++ unicode utf-8 utf-16 c++11
我一直在读一些关于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_convert和wbuffer_convert函数可以使用这些codecvt来直接转换字符串和缓冲区,而不是依赖于流.
C++ 11还包括C99/C11 <uchar.h>标头,其中包含将来自平台多字节编码(可能是或不是UTF-8)的单个字符转换为UCS-2和UCS-4的功能.
但是,这是关于它的程度.虽然你当然可以将UTF-8文本存储在a中std::string,但我无法看到任何对它有用的东西.例如,除了在代码中定义文字之外,您不能将字节数组验证为包含有效的UTF-8,您无法找到长度(即Unicode字符的数量,对于某些"字符"的定义)包含UTF-8 std::string,并且不能std::string以字节为单位以任何方式迭代a .
同样,即使添加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使用UTF-8的BSD衍生的部分,而可可使用UTF-16.
如果你设法阅读了所有这些,谢谢!只是几个简单的问题,因为这毕竟是Stack Overflow ...
以上分析是否正确,或者我是否缺少任何其他支持Unicode的设施?
在过去几年中,标准委员会在快速推进C++方面做得非常出色.他们都很聪明,我认为他们很清楚上述缺点.是否有一个众所周知的原因,即Unicode支持在C++中仍然很差?
展望未来,是否有人知道有任何纠正这种情况的建议?快速搜索isocpp.org似乎没有透露任何信息.
编辑:感谢大家的回复.我不得不承认,我发现它们有点令人沮丧 - 看起来现状在不久的将来不太可能改变.如果在认知方面存在共识,似乎完全的Unicode支持太难了,并且任何解决方案必须重新实现大多数ICU才被认为是有用的.
我个人不同意这一点; 我认为可以找到有价值的中间立场.例如,对于UTF-8和UTF-16的验证和归一化算法是由Unicode财团以及指定的,并且可以通过标准库中,比方说自由函数,一个被提供std::unicode的命名空间.仅这些对于需要与期望Unicode输入的库接口的C++程序来说是一个很大的帮助.但基于下面的答案(微笑,必须说,带着一丝苦涩),似乎Puppy关于这种有限功能的提议并不受欢迎.
n. *_* m. 10
以上分析是否正确
让我们来看看.
您无法将包含有效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和从UTF-16转换std::codecvt_utf8_utf16<char16_t>.转换为UTF-16的结果是UTF-16.它不仅限于BMP.
如果我错过了其他一些"你不能",请指出它,我将解决它.
重要补遗.这些工具在C++ 17 中已弃用.这可能意味着它们将在未来的C++版本中消失.使用它们需要您自担风险.原始问题中列举的所有这些事情现在都不能(安全地)再次使用标准库来完成.
| 归档时间: |
|
| 查看次数: |
4177 次 |
| 最近记录: |