std::string::erase直接删除指定位置范围子串,参数为起始位置和长度,需注意左闭右开区间及越界检查;substr适合生成新字符串但有性能开销;string_view可避免拷贝但无法直接拼接。

用 std::string::erase 删除指定位置范围的子串
直接删,别拼接、别重赋值——erase 就是为此设计的。它接受起始位置和长度(不是结束位置),原地修改,效率高且语义清晰。
- 常见错误:把第二个参数当成“结束索引”,结果删掉远超预期的内容,比如
s.erase(2, 5)想删索引 2~4,实际删了 5 个字符(从 2 开始) - 安全写法:若想删
[left, right)(左闭右开区间),传s.erase(left, right - left) - 越界检查必须做:
left不能超过s.length(),right不能小于left,且right最大取s.length() - 示例:
std::string s = "hello world"; s.erase(6, 5);→"hello "(删掉 "world")
用 substr 拼接实现“减去”但不修改原串
如果你需要保留原字符串,只生成新结果,substr 是最直白的选择。注意它返回新字符串,不改动原串,适合函数式或不可变场景。
- 典型写法:
s.substr(0, left) + s.substr(right),其中right是删除区间的右边界(含) -
substr(pos)从pos到末尾;substr(pos, len)取len个字符——越界时自动截断,不会崩溃但可能不符合预期 - 性能提醒:两次
substr+ 一次+会构造三段临时字符串,短字符串没问题,长文本高频调用建议改用erase原地操作 - 示例:
std::string s = "abcdef"; auto res = s.substr(0, 2) + s.substr(4);→"abef"(删掉索引 2~3 的 "cd")
处理边界情况:空串、越界、left > right
真实代码里这些不是“异常”,而是输入常态。C++ 标准库不会帮你兜底,必须显式判断。
-
erase(pos, len)中若pos >= size(),抛std::out_of_range;len超出剩余长度则只删到末尾 -
substr(pos)若pos > size(),同样抛异常;pos == size()返回空串,合法 - 推荐防御写法:
if (left > right || left > s.size()) return s;,再 clampright = std::min(right, s.size()); - 别依赖“看起来不会越界”——用户输入、解析结果、计算偏移都可能出错
用 std::string_view 避免拷贝(C++17+)
如果只是临时查看“删掉某段后剩下什么”,又不想分配新内存,string_view 是轻量级解法。它不拥有数据,仅提供视图。
- 不能直接“减去”,但可构造两个 view 拼接:
std::string_view sv{s}; auto a = sv.substr(0, left); auto b = sv.substr(right); - 注意:
a和b都指向原字符串内存,只要s不销毁或重排,它们就有效 - 无法直接拼成一个
string_view(非连续内存),需转std::string才能合并:std::string(a).append(b) - 适用场景:日志过滤、协议解析中快速跳过字段,而非构建最终结果
实际用哪一种,取决于你是否允许修改原串、是否在意内存分配、以及调用频次。边界检查不是可选项,是必选项——C++ 不替你做假设。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











