C++ Unicode在C++;11?

C++ Unicode在C++;11?,c++,unicode,c++11,C++,Unicode,C++11,我听说C++11支持Unicode。关于这一点,有几个问题: < C++标准库支持Unicode的情况如何? std::string是否做了它应该做的事情 我如何使用它 潜在问题在哪里 C++11有几个用于Unicode的选项 不幸的是,标准库中对非统一编码(如UTF-8)的支持仍然很差。例如,没有很好的方法来获取UTF-8字符串的长度(以代码点为单位)。您可以安全地将UTF-8存储在std::string(或char[]或char*中,因为Unicode NUL(U+0000)是是UTF-8

我听说C++11支持Unicode。关于这一点,有几个问题:

    < C++标准库支持Unicode的情况如何?<李>
  • std::string
    是否做了它应该做的事情
  • 我如何使用它
  • 潜在问题在哪里
C++11有几个用于Unicode的选项


不幸的是,标准库中对非统一编码(如UTF-8)的支持仍然很差。例如,没有很好的方法来获取UTF-8字符串的长度(以代码点为单位)。

您可以安全地将UTF-8存储在
std::string
(或
char[]
char*
中,因为Unicode NUL(U+0000)是是UTF-8中的空字节,这是UTF-8中出现空字节的唯一方式。因此,UTF-8字符串将根据所有的C和C++字符串函数正确终止,并且可以用C++ iOFFROW(包括<代码> STD::CUT和 STD::CURR < /C> >,只要您的区域是UTF-8)。p> 对于UTF-8,您不能使用
std::string
获取代码点中的长度
std::string::size()
将以字节为单位告诉您字符串长度,这仅等于UTF-8的ASCII子集内的代码点数


如果您需要在级别上操作UTF-8字符串(即,不只是存储和打印它们),或者如果您正在处理UTF-16,它可能有许多内部空字节,那么您需要查看宽字符串类型。

Unicode不受支持(对于支持的任何合理含义)

std::string
并不比
std::vector
更好:它完全不受Unicode(或任何其他表示/编码)的影响,只将其内容视为一个字节块

如果您只需要存储和连接水滴,它工作得非常好;但是,只要您希望使用Unicode功能(number of、number of等),您就不走运了

据我所知,这方面唯一的综合图书馆是。C++接口是从java语言中派生出来的,所以它远不是习惯用法。 < C++标准库支持Unicode?

糟透了

通过快速浏览可能提供Unicode支持的库设施,我可以看到以下列表:

  • 字符串库
  • 本地化库
  • 输入/输出库
  • 正则表达式库
我认为除了第一个以外,所有的都提供了可怕的支持。在快速绕道你的其他问题之后,我会回到更详细的问题上来

std::string
是否做了它应该做的事情

对。根据C++标准,这就是 STD::String 及其兄弟姐妹应该做的:

类模板
basic\u string
描述了可以存储序列的对象,该序列由数量不等的任意类字符对象组成,序列的第一个元素位于零位置

嗯,
std::string
做得很好。这是否提供了任何特定于Unicode的功能?没有

应该吗?可能不会
std::string
作为
char
对象序列很好。这很有用;唯一的烦恼是它是一个非常低级的文本视图,而标准C++没有提供更高层次的文本。 我如何使用它

将其用作
char
对象序列;假装这是另一件事注定会以痛苦告终

潜在问题在哪里

到处都是?让我们看看

字符串库

字符串库为我们提供了
basic_string
,这仅仅是标准所称的“类字符对象”的序列。我称之为代码单位。如果您想要文本的高级视图,这不是您想要的。这是适合序列化/反序列化/存储的文本视图

它还提供了C库中的一些工具,可以用来弥合狭窄世界和Unicode世界之间的鸿沟:
c16rtomb
/
mbrtoc16
C32RTOME
/
mbrtoc32

本地化库

本地化库仍然认为其中一个“类似字符的对象”等于一个“字符”。这当然是愚蠢的,并且使得除了一些小的Unicode子集(比如ASCII)之外,很多事情都无法正常工作

例如,考虑标准在
标题中所称的“便利接口”:

template <class charT> bool isspace (charT c, const locale& loc);
template <class charT> bool isprint (charT c, const locale& loc);
template <class charT> bool iscntrl (charT c, const locale& loc);
// ...
template <class charT> charT toupper(charT c, const locale& loc);
template <class charT> charT tolower(charT c, const locale& loc);
// ...
模板bool-isspace(图表c、const-locale和loc);
模板bool-isprint(图表c、const-locale和loc);
模板bool iscontrl(图表c、const locale和loc);
// ...
模板图表标题(图表c、const locale和loc);
模板图表(图表c、施工现场和loc);
// ...

您希望这些函数中的任何函数如何正确分类,例如U+1F34Cʙᴀɴᴀɴᴀ, 然而,正如在
u8“中一样,有一个非常有用的库,名为它基本上是
std::string
/
std::wstring
的替代品。它旨在填补仍然缺失的utf8字符串容器类的空白


这可能是“处理”utf8字符串的最舒适的方式(也就是说,没有unicode规范化和类似的东西)。您可以轻松地对代码点进行操作,而您的字符串仍然以运行长度编码的
char
s进行编码。

因此,如果我们想支持非拉丁语言,我们是否仍然需要使用std::wstring作为文件名?因为新的字符串文本在这里没有真正的帮助,因为字符串通常来自用户…@Uflex
std::string
可以保留UTF-8字符串没有问题,但例如,
length
方法返回字符串中的字节数,而不是代码点数。老实说,获取字符串的代码点长度没有太多用途。可以使用字节长度来正确预处理字符串