【问题标题】:How do I replace more than one blank in c programming with one blank?如何用一个空格替换 c 编程中的多个空格?
【发布时间】:2025-12-18 10:50:01
【问题描述】:

我是编程新手,我决定从 c 开始。我正在使用 K&R 的书,并且有这个练习,它要求编写一个将输入复制到输出的程序,用一个空格替换一个或多个空格。但是,当我编写程序时(我确信它不正确,但没关系,因为我是来这里学习的)我想知道我做错了什么。另请注意:当我用 3 个空格键入我的名字时,它会减少到两个,但是当使用两个或一个空格时,什么也没有发生。代码贴在下面

#include <stdio.h>
#include <stdlib.h>


int main(void)
{
int c; // getchar value
int blanks = 0; // counting the amount of blanks. If more than one then  replace with blanks_2
char blanks_2 = ' '; //character value for replacement in case blanks is more than one

printf("Enter your name please\n");

while((c = getchar()) != EOF){
if(c == ' '){
    ++blanks;

    if (blanks >= 1){
        putchar(blankos);   }
    }
if(c >= 'a' && c <= 'z'){
    putchar(c);
}
if (c >= 'A' && c <= 'Z'){
    putchar(c);
}

}

return 0;

}

【问题讨论】:

  • 你的意思是用一个空白替换连续的黑色,对吧?
  • 是的。这似乎不起作用@chux。我以前做过类似的事情,但这会使空白回到 0。写我的名字时,我的名字没有空格
  • 给出的答案还不错,但它们并不能帮助您了解您的代码出了什么问题。如果您是编程新手,那么学习跟踪您的代码很重要。所以,一些问题可以帮助您找到 您的 代码中的错误,而不是用其他人的代码替换它:如果您的输入是 'The...noobie.....noob' 会发生什么 [ . =空间]?手动遍历每个字符的循环。跟踪空白的值,并问自己什么时候应该做 putchar,现在什么时候做。当您在单词 2 和 3 之间出现时,行为会发生什么?

标签: c kernighan-and-ritchie


【解决方案1】:

您无需计算确切的空格数。一旦你找到一个空白“升旗”,这个空白就被找到了。当您重新访问非空白字符时,打印一个空白并将标志转回 0。此外,在您的代码中插入“继续”语句以避免不必要的检查:

int main(void)
{
   int c; // getchar value
   int blankfound = 0;

   printf("Enter your name please\n");

   while((c = getchar()) != EOF){
      if(c == ' '){
         blankfound = 1;
         continue;
      }
      if(c >= 'a' && c <= 'z'){
         if (blankfound == 1)
         {
             putchar(' ');
             blankfound = 0;
         }
         putchar(c);
         continue;
      }
      if (c >= 'A' && c <= 'Z'){
          if (blankfound == 1)
          {
             putchar(' ');
             blankfound = 0;
          }
          putchar(c);
          continue;
      }

 }

return 0;

}

【讨论】:

  • 好的,感谢您的建设性反馈。它似乎有效,我理解循环的第一部分,但是你能解释一下为什么每次访问非空白字符时都需要添加一个空白吗?
  • 空白字符被访问的信息保存在blankfound变量中。当当前字符是非空白字符时,会检查 blankfound 变量的值。如果为 1,则表示在当前非空白字符之前至少存在一个空白字符。因此,在打印当前字符值之前,您应该根据任务需要打印一个空白字符。当然...您还应该将 blankfound 转回 0 以识别未来可能出现的空白字符。
【解决方案2】:

我猜你正在尝试编写一个程序来获取这样的输入:

John        David       Doe

并将其显示为输出:

John David Doe

删除所有多余的空格。这应该有效:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int c; // getchar value
    int blanks = 0; // counting the amount of blanks. If more than one then  replace with blanks_2

    printf("Enter your name please\n");

    while((c = getchar()) != EOF)
    {
        if(c == ' ')
        {
            // count blanks
            ++blanks;

            if (blanks==1)     
                putchar(c); // display only the 1st blank
        }

        if(isalpha(c))
        {
            putchar(c);
            blanks=0; // reset blanks counter as c is an alpha character
        }
    }

    return 0;
}

【讨论】:

  • 还没有书中的isalpha函数。刚开始,在第 20 页。虽然我尝试输入代码,但不幸的是它似乎不起作用。
  • isalpha 不等于 not(isspace),这让我想知道您为什么将这个功能引入 noobienoob。
【解决方案3】:

许多学习者代码作业都基于前一个字符的函数概念。

考虑以下布局

int previous = something();
while ((c =  getchar()) != EOF) {
  do_stuff(previous, c);
  previous = c;
}

对于 OP,这将是:如果字符不是空格或前一个字符不是空格,则打印它。

printf("Enter your name please\n");
int previous = 0;
int c;
while((c = getchar()) != EOF) {
  if ((c != ' ') || (previous != ' ')) {
    putchar(' ');
  }
  previous = c;
}

简化算法有助于发现如下缺陷。 blanks 不会在出现字母时重置。它在遇到 1 个或多个空格时打印。

if(c == ' '){
    ++blanks;

    if (blanks >= 1){
        putchar(blankos);   }
    }
if(c >= 'a' && c <= 'z'){
    putchar(c);
}
if (c >= 'A' && c <= 'Z'){
    putchar(c);
}

【讨论】:

    【解决方案4】:

    参考之前的章节(只用了'while'和'if'),我的代码是这样的。

    #include <stdio.h>
    
    main()
    {
        int c;
    
        while ((c = getchar()) != EOF) {
            if (c == ' ') {
                putchar(c);
                while ((c = getchar()) == ' ')
                    ; 
            }
            putchar(c);
        }
    }
    

    【讨论】:

    • 用于编译的gcc -ansi