std::string::length() 返回字节数而非 Unicode 字符数,因 UTF-8 中中文占 3 字节,故”你好”长度为 6 而非 2;应使用 utf8cpp 等库按码点计数。
为什么 std::string::length() 不能直接当“中文字符数”用
因为 UTF-8 编码下,一个中文字符占 3 个字节,std::string::length() 返回的是字节数,不是 Unicode 码点数。比如 "你好" 的 length() 是 6,但你想要的“长度”是 2。
直接按字节遍历或用 std::wstring 也不行:Windows 默认宽字符是 UTF-16(可能有代理对),Linux/macOS 是 UTF-32(看似简单但不跨平台),且 std::wstring 不自带 UTF-8 解码逻辑。
- 别用
str.size()或strlen()当“字符个数” - 别假设
wchar_t在所有平台都一一对应一个汉字(UTF-16 下“?”需要两个wchar_t) - 别手动查字节前缀(如
0xE0–0xEF)却不验证后续字节有效性——会把损坏的 UTF-8 当作合法中文
用 std::mbstowcs() + std::wcslen() 快速估算(仅限本地 locale 支持 UTF-8)
如果确认程序运行环境的 locale 已设为 UTF-8(如 Linux/macOS 默认,Windows 需调用 setlocale(LC_ALL, "en_US.UTF-8") 或 "Chinese_China.65001"),可借助 C 标准库的多字节转换:
std::string s = "Hello世界";
std::vector buf(s.size() + 1); // 保守预分配
size_t len = std::mbstowcs(buf.data(), s.c_str(), buf.size());
if (len != static_cast(-1)) {
int char_count = static_cast(len);
}
注意:mbstowcs 依赖当前 locale,Windows 上若 locale 不匹配(比如仍是 GBK),会把 UTF-8 字节流误判为非法,返回 -1 或截断。
立即学习“C++免费学习笔记(深入)”;