跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C++ 怎么截取字符串 C++ substr函数参数越界处理【API】

substr越界会抛出std::out_of_range异常,因标准要求pos>str.length()或pos+count>str.length()时必须报错;常见原因是直接用find返回的npos(极大值)作pos参数而未校验。 substr 为什么一越界就崩溃?
substr
不做运行时边界检查,越界直接触发
std::out_of_range
异常(debug 模式下可能直接 abort)。这不是“崩溃得不合理”,而是标准明确要求:当
pos > str.length()
或
pos + count > str.length()
且
str
非空时,抛异常。 常见诱因: 用
find
返回的
std::string::npos
直接传给
substr
——
npos
是极大值(如
18446744073709551615
),必然越界 计算起始位置时没校验是否
(虽然 size_t
是无符号,但 隐式转换 后负数会绕成极大值) 传入的
count
过大,比如想取“剩余全部”却硬写
1000
安全截取字符串的惯用写法 别依赖 try/catch 捕获
out_of_range
——性能差、掩盖逻辑缺陷。应该在调用前主动裁剪参数: 起始位置
pos
:用
std::min(pos, str.length())
保证不超长 截取长度
len
:用
std::min(len, str.length() - pos)
,注意先确保
pos
更简洁的写法:
str.substr(pos, std::min(len, str.size() - pos))
,前提是
pos
已合法 示例: 立即学习 “ C++免费学习笔记(深入) ”;
std::string s = "hello"; size_t pos = s.find("xyz"); // 返回 npos if (pos != std::string::npos) { auto sub = s.substr(pos, 2); // 安全 } else { auto sub = ""; // 或 fallback 值 }
npos 传给 substr 的典型错误现场 这是最常被忽略的坑:
std::string::npos
是
size_t
类型的极限值,不是 -1。一旦你把它当整数用,比如
s.substr(s.find("x") + 1)
,
npos + 1
仍是极大值,
substr
必抛异常。 C函数速查手册(CHM版) C函数速查手册(CHM版) 下载 正确做法只有两个: 显式判断
!= npos
后再计算偏移 用
std::string_view
替代(C++17 起),它支持
substr
的宽松语义:越界时自动截断到末尾,不抛异常 例如用
string_view
:
std::string_view sv = s; auto safe_sub = sv.substr(100, 10); // 返回空 view,不崩溃
substr 性能和内存注意点
substr
返回新字符串,意味着堆分配和字符拷贝。如果只是临时读取、不修改,优先用
std::string_view
(C++17)或
const char*
+ 长度;若必须用
substr
,注意: 不要在循环里反复
substr
大字符串的开头(如逐词解析),改用
find
+ 偏移推进 移动语义对
substr
返回值无效——它本来就是新建对象,不存在“移动旧字符串”的优化空间 Release 模式下异常开销小,但避免异常仍是更可控的做法 真正难处理的不是“怎么截”,而是“怎么确定该截哪儿”——
find
/
rfind
的返回值是否为
npos
,这个判断漏掉一次,后面所有
substr
都是定时炸弹。

相关文章