std::string的length()和size()完全等价,均返回字节数(非unicode字符数);c风格字符串需用strlen(),且不支持空指针;获取真实unicode字符数需手动解析或第三方库。

std::string 的 length() 和 size() 完全等价
两者都返回 std::string 中字符的个数(类型为 size_t),底层调用同一段逻辑,没有任何性能或语义差异。C++ 标准明确要求它们行为一致 —— length() == size() 恒成立。
选择哪个纯属风格偏好:length() 更贴近“字符串长度”的自然语义;size() 则与 STL 容器(如 vector、deque)统一命名,便于泛型代码复用。
常见误判是以为 length() 算字节数、size() 算字符数,实际都不是:对 UTF-8 编码的多字节字符(如中文),二者都按 char 计数,即返回字节数,而非 Unicode 字符数。
C 风格字符串要用 strlen(),不能直接用 .length()
如果变量是 const char* 或 char[](比如 char s[] = "hello";),它不是 std::string,没有成员函数 length() 或 size() —— 此时调用会编译失败。
立即学习“C++免费学习笔记(深入)”;
必须用 C 标准库函数:
#include <cstring> const char* cstr = "你好"; size_t len = strlen(cstr); // 返回 6(UTF-8 下“你好”占 6 字节)
-
strlen()在运行时遍历直到遇到'\0',时间复杂度 O(n) - 不检查空指针,传入
nullptr会导致未定义行为 - 对宽字符(
wchar_t*)要用wcslen(),不是strlen()
获取 UTF-8 字符串的真实 Unicode 字符数需手动处理
当字符串含中文、emoji 等时,std::string::length() 返回的是字节数,不是人眼所见的“字数”。例如 std::string s = "??";(一个程序员 emoji),s.length() 可能是 4、7 或更多(取决于 emoji 实现细节),但你只想知道这是 1 个字符。
标准库不提供直接支持,需借助第三方库(如 ICU、utf8cpp)或手写解析:
// 简化版 UTF-8 字符计数(仅适用于合法 UTF-8)
int utf8_char_count(const std::string& s) {
int count = 0;
for (size_t i = 0; i < s.size(); ) {
unsigned char b = s[i];
i += (b & 0x80) == 0 ? 1 :
(b & 0xE0) == 0xC0 ? 2 :
(b & 0xF0) == 0xE0 ? 3 : 4;
count++;
}
return count;
}
注意:该逻辑假设输入是合法 UTF-8;若含乱码或混合编码,结果不可靠。
别混淆 capacity() 和 length()
capacity() 返回当前分配的内存能容纳多少字符,和实际内容长度无关。它可能大于、等于甚至(极少见)小于 length()(后者只在 move 后未清理时短暂发生)。
典型误用场景:
- 用
reserve()后误以为字符串变长了 → 实际length()不变,只是预留空间 - 循环中反复调用
push_back()却没预估容量 → 可能多次 realloc,影响性能 - 把
capacity()当作安全读取边界 → 错!越界访问仍会崩溃
真正需要“长度”的地方,永远优先用 length() 或 size();capacity() 只用于优化内存分配策略。
真实项目里最容易忽略的,是把 C 字符串和 std::string 的长度获取混用,或者在处理国际化文本时,误把 length() 当成“字符个数”来用。这两处一错,bug 往往藏得深、复现难。











