You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++移除字符串多余空格代码 为何未删除单词间单个空格

C++移除字符串多余空格代码逻辑解析

对应实现代码

#include <iostream>
#include <string>
void RemoveExcessSpaces(std::string &s) {
  for (int i = 0; i < s.length(); i++) {
    while (s[i] == ' ')s.erase(s.begin() + i);
    while (s[i] != ' ' && i < s.length())i++;
  }
  if (s[s.length() - 1] == ' ')s.pop_back();
}
int main() {
  std::string s("  this is   string  ");
  RemoveExcessSpaces(s);
  std::cout << "\"" << s << "\"";
  return 0;
}

逻辑解释

你觉得while (s[i] == ' ')s.erase(s.begin() + i);会删掉所有空格,是没捋顺两段while和外层for循环的i自增的配合规则——单词之间的单个空格从头到尾都没被这句删空格的代码碰到,自然会保留下来。
先明确外层for循环的固定执行顺序:每轮循环先跑完大括号里的两段while逻辑,跑完之后才会自动执行一次i++,再判断i是否越界、决定要不要进入下一轮。

  • 第一段删空格的while,只有刚进入本轮循环时,i指向的位置是空格才会触发删除。
  • 第二段while的作用很简单:从当前i位置开始,只要指的不是空格、也没到字符串末尾,就一直把i往后挪,直到碰到第一个空格、或者走到字符串结尾才停下。

拿测试用的字符串" this is string "走一遍关键流程就很清楚:

  1. 初始i=0进第一轮循环:第一段while先把开头两个前导空格全删掉,此时i=0位置是't',删空格逻辑退出;紧接着第二段while一路往后跳过t、h、i、s四个字母,最终i停在"this"后面的第一个空格位置(索引4),这时候本轮循环体跑完了,外层for自动做一次i++,i直接变成5,刚好把索引4位置的那个单个空格跳了过去。
  2. i=5进第二轮循环:此时s[5]是"is"的首字符'i',根本不是空格,删空格的while连触发都不会触发;紧接着第二段while往后跳过i、s两个字母,i停在"is"后面的第一个空格位置(索引7),本轮循环结束,外层for又自动做一次i++把i改成8,又跳过了索引7位置的单个空格。
  3. i=8进第三轮循环:"is"后面总共有3个连续空格,索引7是刚才被跳过的第一个空格,索引8、9都是多出来的空格,此时s[8]是空格,删空格的while触发,连续删掉这两个多余空格,直到i=8位置变成"string"的首字符's'才停;之后第二段while跳过s、t、r、i、n、g所有字母,i停在字符串尾部的空格位置,本轮跑完后for的i++直接走到字符串长度位置,外层循环结束。
  4. 最后执行尾部判断,把残留的末尾空格删掉,最终输出就是正确的"this is string"。

说白了这段代码的效果就是:每遇到连续空格,只留最靠近前一个单词的那一个,剩下的全删掉,刚好符合去多余空格的要求。

顺带提一句,这段代码有边界bug,如果传入空字符串,访问s[s.length() - 1]会直接越界,实际用的时候要补个空串判断。

内容的提问来源于stack exchange,提问作者Rocket Procd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 09:03:21