简短的回答:没有好的答案。文字很复杂。
首先,您需要确定要查找的“长度”以找出要调用的内容。
在您的示例中, std::string::size() 以 C 字符(即字节)提供长度。正如毗湿奴指出的,字符“é”的长度是 2 个字节,而不是 1。
另一方面,如果您按照 Duncan 的建议切换到 std::wstring::size(),它将开始测量 UTF-16 代码点的大小。在这种情况下,字符“é”是 1 个 UTF-16 代码点。
切换到 wstring 似乎是解决方案,但这取决于您在做什么。例如,如果您尝试获取字符串的大小以分配缓冲区(以字节为单位),则 std::string::size() 可能是正确的,但 std::wstring::size()是错误的,因为每个 UTF-16 代码点需要 2 个字节来存储。(从技术上讲,std::wstring 正在存储 wchar_t 字符,甚至不一定在 UTF-16 中,并且每个代码点都需要 sizeof(wchar_t) 字节来存储......所以它通常不会真正起作用,无论如何。)
即使您只想要“一个人会看到的字符数”(字形的数量),切换到 wstring 也不适用于更复杂的数据。例如,“é”(字符 http://www.fileformat.info/info/unicode/char/e9/index.htm'>U+00E9)是 1 个 UTF-16 码位,但“é”也可以表示作为“e”加上一个组合的重音(字符 http://www.fileformat.info/info/unicode/char/0301/index.htm'>U+0301)。您可能需要阅读有关 Unicode 规范化的信息。在某些情况下,单个“字符”需要 2 个 UTF-16 代码点,称为代理对——尽管许多软件安全地忽略了这些。
老实说,使用 Unicode,您要么必须接受无法处理所有边缘情况的事实,要么必须放弃一次处理一个“字符”,而是只处理一个“单词”(一串由空格分隔的代码点)以使事情正常工作。然后你会问你正在使用的库——例如,一个绘图库——每个“单词”有多宽,并希望他们正确处理了所有的重音、组合字符、代理对等。