EOF не завершается при попытке считать слова в C - PullRequest
0 голосов
/ 04 декабря 2018

Я читаю 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;
}

Ответы [ 4 ]

0 голосов
/ 04 декабря 2018

Я знаю, что я обманываю, но этот пример показывает, как функции более высокого уровня делают программы более понятными.scanf '%s преобразование делает разделение слов для нас.В примере используется символ подавления присваивания *, который устраняет необходимость предоставлять место для произвольно длинных слов, которые мы на самом деле не хотим знать.

#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;
}
0 голосов
/ 04 декабря 2018
while((c = getchar()) != EOF) {
    while(c != ' ' && c != '\t' && c != '\n') {
      wc++;
    }
  }

Когда вы нажимаете клавишу в первый раз, внутренний цикл while срабатывает и никогда не завершается, если только первая клавиша не входит в число тех, которые находятся в условии.

Поэтому, если вы нажмете 'A', внутренний цикл whileпродолжается вечно.

Вам нужно заменить while на if.И измените условие таким образом, что wc будет увеличиваться только тогда, когда встречается или другой указанный символ, и getchar() будет выполняться для получения следующего символа.

0 голосов
/ 04 декабря 2018

Следующий пример немного ближе к подсчету слов :

#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;
}
0 голосов
/ 04 декабря 2018

Мне пришлось добавить 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;
}
...