最轻量方式是用 std::string::find_first_not_of 和 find_last_not_of 手动截取,需显式传入" "并检查 npos;regex_replace 一行解决但性能差;isspace 循环删除有 locale 依赖和 O(n²) 缺陷;Boost::trim 简洁但修改原串。

用 std::string::find_first_not_of 和 std::string::find_last_not_of 手动截取
这是最轻量、不依赖额外库的方式,适合所有标准 C++(C++98 起可用)。核心思路是:先找第一个非空格位置,再找最后一个非空格位置,然后用 substr 截取中间部分。
注意:find_first_not_of 默认把空格、制表符、换行等都算作“空白”需显式指定;若只去 ASCII 空格(' '),必须传入字符串字面量 " ",不能只写 ' '(函数不接受单字符)。
常见错误现象:find_last_not_of(" ") 对全空格字符串返回 std::string::npos,直接用于 substr 会触发未定义行为。
- 务必先判断
first != std::string::npos,否则整个字符串为空或全空格,应返回空串 - 计算长度时用
last - first + 1,但需确保last >= first(find_last_not_of在空串中也返回npos) - 示例代码:
std::string trim(const std::string& s) {
size_t first = s.find_first_not_of(" ");
if (first == std::string::npos) return {};
size_t last = s.find_last_not_of(" ");
return s.substr(first, last - first + 1);
}用 std::regex_replace 一行解决(C++11 起)
适合已有正则使用习惯、且不介意轻微性能开销的场景。正则表达式 ^\s+|\s+$ 可同时匹配行首和行尾的空白(\s 包含空格、\t、\n、\r 等)。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
性能影响明显:每次调用都需编译正则(除非缓存 std::regex 对象),对高频调用(如解析日志)不推荐。
- 必须用原始字符串字面量
R"(^s+|s+$)"避免反斜杠转义问题 - 默认
std::regex不启用ECMAScript外的语法,\s是安全的 - 若只需去 ASCII 空格,正则写成
R"(^ +| +$)"更快
为什么不要用 std::isspace 配合循环手动删?
有人会遍历首尾字符,逐个调用 std::isspace(int) 判断并 erase。这看似直观,但有三个硬伤:
-
std::isspace行为依赖当前 locale,"C"locale 下才可靠识别 ASCII 空白;其他 locale 可能误判非 ASCII 字符(如 UTF-8 中文空格) -
erase在头部删除会引发后续字符内存移动,O(n²) 时间复杂度,对长字符串很慢 - 容易漏掉
或,而find_first_not_of(" ")显式列出更可控
第三方方案:Boost.StringAlgorithms 的 boost::trim
如果项目已用 Boost,boost::algorithm::trim 是最省心的选择——它默认处理所有 C 风格空白(\s 级别),原地修改,接口简洁。
但要注意:它修改原字符串,不是返回新副本;若需 const 正确性,得配合 boost::algorithm::trim_copy。
- 头文件是
<boost/algorithm/string.hpp>,不是string_algo - 不支持仅去空格(
' ')而不去' ',如需精确控制,还是回退到find_*方案 - 链接时无需额外库,纯头文件
实际用哪个,取决于你是否需要兼容旧标准、是否已在用 Boost、以及对空白字符范围的定义精度。最常被忽略的是全空格字符串的边界处理——find_first_not_of 返回 npos 后不检查就 substr,程序大概率崩溃。

















