用 substr(0, str.length()-n) 可安全截掉字符串末尾 n 个字符,但需先检查长度;resize() 更高效但会修改原串;C 风格字符串需谨慎处理终止符;UTF-8 字符串按字节截可能破坏字符完整性。

用 substr() 截掉固定长度字符串的末尾字符
直接调用 substr() 并传入起始位置和长度即可,不需要手动遍历或构造新字符串。前提是知道要保留多少字符——比如原字符串长 10,想删掉最后 2 个,就取前 8 个。
常见错误是误用 substr(pos) 单参数形式(它会从 pos 截到末尾),或者对空字符串、截取长度超界没做防护。
-
str.substr(0, str.length() - n)是最常用写法,n是要删的尾部长度 - 必须检查
str.length() >= n,否则substr()抛std::out_of_range - 如果
n == 0,直接返回原串;如果n >= str.length(),结果为空串(不是崩溃,但需按业务判断是否合理)
用 resize() 原地截断更高效
如果只是单纯删尾、不关心原字符串后续使用,resize() 比 substr() 少一次内存分配,尤其对长字符串或高频操作更合适。
注意:这会修改原字符串对象,且不可逆;而 substr() 返回新串,原串不变。
立即学习“C++免费学习笔记(深入)”;
-
str.resize(str.length() - n);—— 简洁,但同样要先判断长度是否足够 - 对
std::string_view不适用(它是只读视图,没有resize()) - 如果字符串是 const 或绑定在容器里(如
const std::string&),只能用substr()
处理 C 风格字符串(char*)时不能直接截断
C 字符串以 '\0' 结尾,所谓“截断尾部”本质是改写终止符位置。但必须确保缓冲区可写、且有足够空间容纳新终止符。
直接改 ptr[len - n] = '\0' 看似简单,实际极易越界或破坏相邻内存。
- 安全做法:用
strncpy()到新缓冲区,或用std::string(ptr).substr(0, len - n).c_str()中转 - 若确定源缓冲区够大且可写,才可手动置
'\0',例如:buf[std::min(len, static_cast<size_t>(n)) ? len - n : 0] = '\0';</size_t> - 永远不要对字面量字符串(如
"hello")做这种操作——它们通常存在只读段,运行时崩
边界情况:空串、负数、Unicode 字符
std::string 是字节序列,不是字符序列。如果字符串含 UTF-8 编码的中文或 emoji,按字节截可能切开一个字符,导致后续解析出错。
标准库不提供 UTF-8 安全截断,真有此需求得引入 ICU 或手写 UTF-8 解码逻辑。
- 纯 ASCII 场景下,按字节截完全安全
- 遇到
""、n (编译器不会报错,但 <code>size_t无负值,会转成极大正数)必须提前校验 - 调试时打印
str.length()和str.size()(二者等价),别依赖strlen()对std::string的结果
真正麻烦的从来不是“怎么删”,而是删完后那个字符串还合不合预期——尤其是跨编码、跨所有权、跨线程时。留神那些看似无害的 resize() 和裸指针操作。


















