用std::regex_replace一行可将连续空白替换为单空格,但会误转制表符换行符且性能差;双指针法精准处理仅ASCII空格;std::unique不适用;istringstream适合纯文本清洗但丢失格式。

用 std::regex_replace 一行搞定但要注意性能
直接替换多个连续空格为单个空格最省事:std::regex_replace(s, std::regex("\s+"), " ")。但注意:它会把所有空白字符(包括 、
)全换成空格,且正则在短字符串上开销明显。如果只是处理用户输入的普通文本,够用;高频循环里别这么写。
手写双指针更可控,适合严格只处理 ASCII 空格
真正想“合并连续的 ' '、不碰制表符或换行”,就得自己遍历。核心逻辑是读写双索引:跳过开头空格,遇到非空格就写入,再跳过后续所有空格,直到下一个非空格字符。
关键点:
- 先用
erase去掉开头空格(或手动跳过),否则结果开头多一个空格 - 写入时用
str[write++] = str[read],不是push_back,避免重复扩容 - 结尾记得
str.resize(write),不然后面残留旧内容
std::unique 配合 lambda 不适用这个场景
有人试 std::unique,以为能去重相邻空格——不行。std::unique 只删“相邻且相等”的元素,而你想要的是“把一串空格压缩成一个”,不是“去掉重复空格”。比如 "a b"(两个空格)经 unique 还是 "a b",因为它只比较相邻位置:第1个空格和第2个空格相等,删第2个 → 得 "a b";但 "a b"(三个空格)删完只剩两个,还是多的。它解决不了“多→一”的归约问题。
立即学习“C++免费学习笔记(深入)”;
用 std::istringstream 拆再拼,简单但有副作用
std::istringstream iss(s); std::string word; std::string result; while (iss >> word) { if (!result.empty()) result += " "; result += word; } 这种方式天然跳过所有空白并用单空格连接。但它会丢失原始字符串中的换行/制表语义,且额外分配内存。适合最终只要“单词间单空格”的纯文本清洗,不适合保留格式结构的场景。
真正难的不是怎么写,而是想清楚:你要的是“视觉上空格变少”,还是“语义上单词分隔标准化”——前者得保留下标位置信息,后者直接拆串最稳。没想清这点,代码写完还得返工。


















