string::length()和string::size()完全等价,均返回字符个数(不含'\0'),类型为size_t;c_str()和data()返回指针,含'\0'时strlen()会误截断,应直接用length()/size();字面量需用strlen()或sizeof-1;string_view构造时须显式传长度以防截断;size_t减法易溢出。

string::length() 和 string::size() 完全等价,选哪个都行
它们是同一个函数的两个名字,底层都是返回 std::string 内部存储的字符个数(不包括终止符 '\0'),类型都是 size_t。C++ 标准明确要求二者行为一致,编译器不能搞区别对待。
常见错误现象:有人看到文档里两个函数并列就以为有隐含差异,比如“length() 算字节,size() 算字符”,纯属误解;也有人在代码审查里挑刺说“统一用 size()”,其实没技术依据。
- 使用场景上,
length()更贴近字符串语义(比如“这个字符串多长”),size()更贴近容器通用接口(vector::size()、array::size()) - 如果你混用 STL 容器,统一用
size()可读性略高;如果专注文本处理,length()更自然 - 性能、ABI、优化层面——零差异。内联后就是一条
return _Mysize;
c_str() 和 data() 返回的 C 风格字符串长度不是靠 strlen() 判断
很多人写 strlen(s.c_str()) 或 strlen(s.data()) 来“确认长度”,这不仅多余,还埋下隐患:如果字符串含 '\0'(合法!std::string 允许中间有空字符),strlen() 会提前截断,结果错误。
正确做法永远是调用 s.length() 或 s.size() ——它直接读成员变量,快且准确。
立即学习“C++免费学习笔记(深入)”;
-
c_str()保证以'\0'结尾,data()在 C++11 后也保证(C++17 起二者完全等价) - 但它们返回的指针只是“可读”,不代表内容是 C 字符串语义;含嵌入
'\0'时,strlen()失效 - 跨平台尤其要注意:Windows API 或旧 libc 函数若依赖
strlen()行为,传string::data()前必须确认无内嵌'\0'
char* 字面量和 C 风格字符串的长度不能用 .length(),得用 strlen() 或 sizeof
"hello" 是 const char[6] 类型,不是 std::string,没有 .length() 成员。硬写会编译失败。
两种安全方式:
- 用
strlen("hello")—— 运行时计算,适用于变量指向的字符串 - 用
sizeof("hello") - 1—— 编译期常量,仅限字面量(因为"hello"类型含末尾'\0') - 别用
std::string("hello").length()做“取长度”,构造临时对象不必要,且掩盖了原始类型意图 - C++11 起可用
std::char_traits<char>::length("hello")</char>,但太冷门,没必要
std::string_view 的 length() / size() 行为一致,但注意空字符截断风险
std::string_view 的 length() 和 size() 同样等价,返回的是构造时指定的长度,不扫描内容。
关键区别在于:它不拥有数据,所以构造时若用 strlen() 算长度,就会重蹈上面的坑。
- 正确构造:
std::string_view sv{"hello\0world", 11};—— 显式传长度,保留全部内容 - 危险构造:
std::string_view sv{"hello\0world"};—— 依赖strlen(),实际只看到"hello" - 从
std::string构造最安全:std::string s = "a\0b"; auto sv = std::string_view(s);,此时sv.length()是 3 - 只要没显式传长度,
string_view构造函数默认走strlen(),这点和std::string不同
真正容易被忽略的是:所有这些长度接口返回的都是 size_t,做减法或和有符号整数比较时极易触发隐式转换和溢出——比如 if (s.length() - 10 > 0) 在 s 很短时,s.length() 是无符号,减法会绕回极大值。









