std::string::size() 返回字节数而非字符数;utf-8 中文字符串如"你好"返回6字节但仅2字符;std::wstring::size() 返回wchar_t元素个数,字节数需乘sizeof(wchar_t);utf-8字符数须手动解析或多字节库计算。

std::string::size() 返回的是字节数,不是字符数
在 C++ 中,std::string 本质是 std::basic_string<char></char>,底层存储的是连续的 char 字节序列。所以 str.size() 或 str.length() 直接返回的就是字节数——这点和 Python 的 len()(对 str 返回字符数)完全不同,容易误判。
- 对 ASCII 字符串(如
"hello"),字节数 = 字符数 = 5 - 对 UTF-8 编码的中文字符串(如
"你好"),每个汉字占 3 字节,str.size()返回 6,但只有 2 个 Unicode 字符 - 若字符串含 BOM 或混合编码(如误把 GBK 数据存进
std::string),size()仍返回实际字节数,但语义上已不表示“有效字符长度”
std::wstring 怎么算字节数?别直接用 .size()
std::wstring 是 std::basic_string<wchar_t></wchar_t>,其 .size() 返回的是 wchar_t 元素个数,不是字节数。真正字节数取决于 wchar_t 在平台上的宽度:
- Windows(MSVC):
wchar_t是 16 位 →str.size() * sizeof(wchar_t)= 字节数(通常为 ×2) - Linux/macOS(GCC/Clang):
wchar_t是 32 位 → 字节数 =str.size() * 4 - 因此必须显式乘以
sizeof(wchar_t),不能直接用.size()
示例:std::wstring s = L"中";,在 Windows 上 s.size() 是 1,但字节数是 sizeof(wchar_t) == 2;在 Linux 上字节数是 4。
UTF-8 字符串想获取真实字符数?得自己遍历解析
如果字符串是 UTF-8 编码(常见于跨平台文本处理),std::string::size() 给你的是字节数,而你要的是 Unicode 码点数量(即“有几个字符”),这时不能靠标准库直接得出,必须解析 UTF-8 多字节序列:
- 标准库无内置 UTF-8 解析函数(C++20 引入了
std::text_encoding,但尚未普及且不提供计数接口) - 可手写简单判断:检查每个字节高位模式(
0xxxxxxx是 ASCII,110xxxxx开头是 2 字节字符,依此类推) - 更稳妥用轻量库如
utf8cpp:utf8::distance(str.begin(), str.end())返回码点数 - 注意:代理对(surrogate pairs)在 UTF-8 中不存在,无需额外处理;但若输入非法 UTF-8,需决定是否容错
从文件或网络读取后,字节数可能受换行符影响
读取文本时,不同系统换行符占用字节数不同,会影响最终 std::string 的 size():
- Unix/Linux:换行是
'\n'(1 字节) - Windows:换行常为
"\r\n"(2 字节),若以文本模式打开文件,C++ 运行时可能自动转换为单个'\n'(取决于编译器和 mode) - 二进制模式读取则严格保留原始字节,
size()就是真实字节数,但需自行处理换行逻辑 - 网络协议(如 HTTP body)通常按原始字节传输,
size()可直接用于 Content-Length 计算
真正麻烦的是:你得先确认字符串的编码和来源上下文——是 raw bytes?还是已解码的 UTF-8?还是误当 UTF-8 解释的 GBK?字节数本身永远准确,但它的含义取决于你怎么用它。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











