计算 std::string 中的实际字符数(不是字符)?

jcj*_*rez 3 c++ string unicode

我可以计算 std::string 包含的“字符数”而不是字节数吗?例如,std::string::size返回std::string::length字节数(字符):

\n
std::string m_string1 {"a"};\n// This is 1\nm_string1.size();\n\nstd::string m_string2 {"\xd1\x97a"};\n// This is 3 because of Unicode\nm_string2.size();\n
Run Code Online (Sandbox Code Playgroud)\n

有没有办法获取字符数?例如要获得它们m_string2有2个字符。

\n

use*_*522 5

一般而言,不可能使用 C++ 标准库中的任何内容来计算 Unicode 字符串中的“字符”。目前尚不清楚“字符”到底是什么意思,您能得到的最接近的结果是使用 UTF-32 文字和std::u32string. 然而,这甚至不符合您想要的\xd1\x97a

\n

例如\xd1\x97可能是单个代码点

\n
\xd1\x97 CYRILLIC SMALL LETTER YI' (U+0457)\n
Run Code Online (Sandbox Code Playgroud)\n

或两个连续的代码点

\n
\xd1\x96 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I (U+0456)\n\xe2\x97\x8c\xcc\x88 COMBINING DIAERESIS (U+0308)\n
Run Code Online (Sandbox Code Playgroud)\n

如果你不知道字符串是否已标准化,那么你无法用标准库区分两者,也没有办法强制标准化。即使对于 UTF-32 字符串文字,选择哪一种也取决于实现。对于一个字符串你会得到 2 或 3\xd1\x97a计算代码点时,

\n

这甚至没有考虑您在问题中提到的编码问题。每个代码点本身可以​​根据所选编码被编码为多个代码单元,并且.size()计算的是代码单元,而不是代码。这两者至少会一致std::u32string,即使它对您没有帮助,正如我上面演示的那样。

\n

如果你想正确地做到这一点,你需要一些像 ICU 这样的 unicode 库。

\n