Обнаружение EOF в C

Я использую следующий код C для ввода от пользователя, пока не произойдет EOF, но проблема в том, что этот код не работает, он завершается после первого ввода. Может кто-нибудь сказать мне, что не так с этим кодом. Спасибо заранее.

float input;

printf("Input No: ");
scanf("%f", &input);

while(!EOF)
{
    printf("Output: %f", input);
    printf("Input No: ");
    scanf("%f", &input);
}

6 ответов


EOF это просто макрос со значением (обычно -1). Вы должны проверить что-то против EOF, таких как getchar() звонок.

один из способов проверить конец потока - это


EOF является константой в C. Вы не проверяете фактический файл для EOF. Вам нужно сделать что-то вроде этого

while(!feof(stdin))

вот документация для feof. Вы также можете проверить возвращаемое значение функции scanf. Он возвращает количество успешно преобразованных элементов, или EOF если он достигает конца файла.


другая проблема заключается в том, что Вы читаете с scanf("%f", &input); только. Если пользователь вводит что-то, что нельзя интерпретировать как число с плавающей запятой C, например "pi",scanf() call ничего не назначит input, и не будет прогрессировать оттуда. Это означает, что он попытается продолжить чтение "pi" и потерпит неудачу.

учитывая изменение while(!feof(stdin)) какие другие плакаты правильно рекомендуют, если вы набрали "pi" , там будет бесконечный цикл печати прежнего значения input и печать приглашения, но программа никогда не будет обрабатывать новый ввод.

scanf() возвращает количество назначений для входных переменных, которые он сделал. Если он не сделал назначения, это означает, что он не нашел число с плавающей запятой, и вы должны прочитать больше ввода с чем-то вроде char string[100];scanf("%99s", string);. Это приведет к удалению следующей строки из входного потока (до 99 символов, в любом случае-extra char для нулевого символа в строке).

вы знаешь, это напоминает мне обо всех причинах, по которым я ненавижу scanf() и почему я использую fgets() вместо этого, а затем, возможно, разобрать его с помощью sscanf().


в качестве отправной точки можно попробовать заменить

while(!EOF)

С

while(!feof(stdin))

вы хотите проверить результат scanf (), чтобы убедиться, что было успешное преобразование; если нет, то одна из трех вещей истинна:

  1. scanf () задыхается от символа, который недопустим для спецификатора преобразования %f (т. е. чего-то, что не является цифрой, точкой, " e " или "E");
  2. scanf () обнаружил EOF;
  3. scanf () обнаружил ошибку при чтении stdin.

пример:

int moreData = 1;
...
printf("Input no: ");
fflush(stdout);
/**
 * Loop while moreData is true
 */
while (moreData)
{
  errno = 0;
  int itemsRead = scanf("%f", &input);
  if (itemsRead == 1)
  {
    printf("Output: %f\n", input);
    printf("Input no: ");
    fflush(stdout);
  }
  else
  {
    if (feof(stdin))
    {
      printf("Hit EOF on stdin; exiting\n");
      moreData = 0;
    }
    else if (ferror(stdin))
    {
      /**
       * I *think* scanf() sets errno; if not, replace
       * the line below with a regular printf() and
       * a generic "read error" message.
       */
      perror("error during read");
      moreData = 0;
    }
    else
    {
      printf("Bad character stuck in input stream; clearing to end of line\n");
      while (getchar() != '\n')
        ; /* empty loop */
      printf("Input no: ");
      fflush(stdout);
    }
 }

while(scanf("%d %d",a,b)!=EOF)
{

//do .....
}