std::string 的 size() 和 length() 完全等价,返回 std::string::size_type(通常为 size_t),与有符号整数比较易引发隐式转换问题。

用 size() 或 length() 获取 std::string 长度
直接调用成员函数就行,size() 和 length() 完全等价,返回 std::string::size_type(通常是 size_t),不是 int。
常见错误是拿它和有符号整数比较,比如写 if (s.size() —— 这里 <code>size() 是无符号类型,-1 会被转成极大正数,条件永远为假。
- 始终用
auto len = s.size();或显式转成ssize_t(C++20 起有ssize())来避免隐式转换问题 - 不要对空字符串调用
at(0)之类操作来“试探长度”,这是越界行为,不是测长度的手段 -
size()是 O(1),内部只读一个字段,不用怕频繁调用
strlen() 只能用于 C 风格字符串,不能传 std::string
新手常写 strlen(s),其中 s 是 std::string,编译直接报错:cannot convert 'std::string' to 'const char*'。
如果真要穿给 strlen(),必须用 s.c_str() 或 s.data()(注意:C++11 起 data() 保证结尾有 \0,可安全用)。
立即学习“C++免费学习笔记(深入)”;
-
strlen(s.c_str())和s.size()结果一样,但多一次遍历,纯属浪费 -
strlen()对非 null-terminated 字符串会越界读,std::string允许含\0,此时s.c_str()仍以第一个\0截断,strlen()返回值可能小于s.size() - 跨函数传参时,若接口要求
const char*,优先用s.c_str();若只是算长度,别绕路
计算 UTF-8 字符串“字符数”不能靠 size()
s.size() 返回的是字节数,不是 Unicode 字符个数。比如中文字符在 UTF-8 下占 3 字节,"你好".size() 是 6,但人眼看到的是 2 个字符。
标准库不提供 Unicode 字符计数,得靠第三方库(如 ICU、utf8cpp)或手写解析逻辑。
- 简单判断:如果字符串只含 ASCII(0x00–0x7F),
size()≡ 字符数 - 用
std::count_if(s.begin(), s.end(), [](unsigned char c) { return (c & 0xC0) != 0x80; })可粗略统计 UTF-8 code point 数(跳过 continuation byte),但不处理代理对、组合字符等边界情况 - 生产环境别自己写 UTF-8 解析,容易漏掉 BOM、无效序列、超长编码等问题
用 std::string_view 时长度获取方式一致
std::string_view 的 size()、length()、empty() 行为和 std::string 完全相同,且同样 O(1)。
区别在于:它不拥有数据,所以 data() 指向的内存必须在 string_view 生命周期内有效——长度算得再准,指针悬空也没用。
- 从
std::string构造string_view很安全:std::string_view sv{s}; - 从字面量构造也安全:
std::string_view sv{"hello"};(字面量寿命是静态的) - 但从局部
char[]或临时std::string的c_str()构造就危险,长度值没错,但后续访问data()可能崩溃
s.size()。真正卡住人的,往往不是“怎么算”,而是算完拿这个数去干了什么——比如当成 int 传进 API、当成字符数去切分 UTF-8、或者当成有效索引上限却忘了空字符串边界。











