最直接删所有空格用 str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char c) { return std::isspace(c); }), str.end()),注意 std::isspace 必须传 unsigned char;首尾去空推荐 find_first_not_of/find_last_not_of 配合子串截取;c++20 可用 std::ranges::erase_if 简化。

用 std::string::erase + std::isspace 删除所有空格
想彻底去掉字符串里每个空格(包括中间的),最直接的方式是遍历并擦除。注意不能用普通 for 循环配合 erase 边遍历边删,否则会跳过下一个字符——因为擦除后后续字符前移,而索引却继续加一。
推荐写法是反向遍历,或用迭代器配合 remove_if + erase(惯用法):
str.erase(std::remove_if(str.begin(), str.end(), [](unsigned char c) {
return std::isspace(c);
}), str.end());
-
std::isspace必须传unsigned char或EOF,否则对负值 char(如某些 locale 下的扩展 ASCII)可能未定义行为 - 这个操作会删除所有空白符:空格、
'\t'、'\n'、'\r'、'\f'、'\v',不只是空格 - 若只想要删 ASCII 空格(
' '),直接写c == ' '更安全、更快
用 find_first_not_of 和 find_last_not_of 去首尾空格
标准库没提供原地 trim 函数,但可以用两个查找函数定位有效字符边界,再取子串。这是最常用、最轻量的首尾去空方案:
size_t start = str.find_first_not_of(" \t\n\r\f\v");
size_t end = str.find_last_not_of(" \t\n\r\f\v");
if (start == std::string::npos) {
str.clear(); // 全空白
} else {
str = str.substr(start, end - start + 1);
}
- 字符串字面量
" \t\n\r\f\v"包含全部 C 风格空白符,和std::isspace行为一致 - 必须检查
start == npos,否则substr可能抛std::out_of_range - 不要用
str.erase(0, start)再erase尾部——多次内存移动,性能差
为什么不用 boost::algorithm::trim
如果你项目已依赖 Boost,boost::algorithm::trim 确实简洁:
立即学习“C++免费学习笔记(深入)”;
boost::algorithm::trim(str); // 原地去首尾空白
但它默认只处理 ASCII 空格和制表符,不包含 '\n' 等;且若你只是临时处理字符串,引入 Boost 显得过重。更关键的是:它的内部实现仍是调用 find_first_not_of 类逻辑,没有本质优势。
- 若需跨平台一致处理所有空白符,仍建议手写带完整空白集的版本
- Boost 版本在 C++20 之前不支持视图(
std::string_view),无法避免拷贝 - 很多嵌入式或严控依赖的项目禁用 Boost,这时标准库方案是唯一选择
C++20 起可用 std::ranges::erase 简化操作
C++20 引入了范围算法,删所有空格可以写成一行,语义清晰且无需 lambda:
std::ranges::erase(str, ' '); // 仅删空格字符
// 或删所有空白符(需自定义谓词,仍需 <code>std::isspace</code>)
std::ranges::erase_if(str, [](unsigned char c) { return std::isspace(c); });
-
std::ranges::erase是无副作用的就地删除,比传统remove_if + erase更直观 - 但要注意:它要求编译器开启 C++20 模式,且部分老版本 STL(如 GCC 10 默认 libstdc++)尚未完全支持
- 目前(2024 年主流环境)
remove_if + erase兼容性仍是最稳的选择
实际使用时,首尾 trim 的边界检查和空白字符集定义最容易被忽略;全删空格时,std::isspace 的参数类型错误会导致偶发崩溃——尤其在非 English locale 下。











