尝试计算 C 中的单词时 EOF 没有终止

EOF not terminating when trying to count words in C

我正在阅读 K&R,其中一个代码计算字数。我决定尝试制作我自己的代码版本,但是使用我当前的代码,EOF(Ctrl+D 因为我在 Linux)不工作。

#include <stdio.h>

int main(void) {
  int c, wc = 0;

  while((c = getchar()) != EOF) {
    while(c != ' ' && c != '\t' && c != '\n') {
      wc++;
    }
  }

  printf("%d", wc);

  return 0;
}

我必须将 getchar() 添加到内部 while 循环中。

#include <stdio.h>

int main(void) {
  int c, wc = 0;

  while((c = getchar()) != EOF) {
    while((c = getchar()) != ' ' && c != '\t' && c != '\n');
    wc++;
  }

  printf("%d\n", wc);

  return 0;
}
while((c = getchar()) != EOF) {
    while(c != ' ' && c != '\t' && c != '\n') {
      wc++;
    }
  }

当您第一次按下一个键时,内部 while 循环会触发并且永远不会退出,除非第一个键是条件中的一个。

因此,如果您按下 'A',内部 while 循环将永远持续下去。

您需要将 while 替换为 if。并以 wc 仅在遇到或其他指定字符时才递增的方式修改条件,并且将执行 getchar() 以获取下一个字符。

下面的例子更接近于计算字数:

#include <stdio.h>

int main(void) {
  int c, wc = 0;
  int sep = 1;
  while((c = getchar()) != EOF) {
    if (c != ' ' && c != '\t' && c != '\n') {
      if ( sep ){
        wc++;
        sep = 0;
      }
    }
    else
      sep = 1;
  }

  printf("%d", wc);

  return 0;
}

我知道我在作弊,但这个例子展示了高级函数如何使程序更清晰。 scanf%s 转换为我们进行分词。该示例使用 * 赋值抑制字符,它避免了为我们实际上不想知道的任意长单词提供 space 的需要。

#include <stdio.h>

int wordcount = 0;

int main(void) {

  while(scanf("%*s") != EOF) 
  {
    wordcount++;
  }
  printf("%d\n", wordcount);
  return 0;
}

如果我必须自己滚动它,我会编写子例程。看看 main 看起来多干净!

#include <stdio.h>

/** @return 1 if c is whitespace, else 0. */
static int isWhite(int c);

/** When this function returns, c is either EOF or non-whitespace.
    @return c
*/
static int readWhite();

/** When this function returns, c is either EOF or whitespace.
    @return c
*/
static int readWord();

int main(void) {

  int wordcount = 0;

  while(readWhite() != EOF)
  {
    wordcount++;
    readWord();
  }

  printf("%d\n", wordcount);
}

//////////////////////////////////////////////////////
static int isWhite(int c)
{ 
  return c == '\n' || c == '\t' || c == ' '; 
}
//////////////////////////////////////////////////////
static int readWord()
{
  int c;
  while((c = getchar()) != EOF && !isWhite(c))
  {
    ; // this statement intentionally left blank
  }
  return c;
}
//////////////////////////////////////////////////////
static int readWhite()
{
  int c;
  while((c = getchar()) != EOF && isWhite(c))
  {
    ; // this statement intentionally left blank
  }
  return c;
}