Как EOF действует в getchar () и scanf () в системе Windows? - PullRequest
0 голосов
/ 31 октября 2018

У меня есть две части кода, чтобы проверить, как две функции консольного ввода-вывода, getchar () и scanf (), обрабатывают EOF. Но у меня все еще нет ясного понимания фактических операций за выходами и их поведения. Может кто-нибудь объяснить это для меня? Большое спасибо! (Я использую ОС Windows)

// 1st piece of Code
#include <stdio.h>
#include <ctype.h>

int main(void)
{
   char ch;

   while ((ch=getchar()) != EOF)
   {
      putchar(toupper(ch));
   }

   return 0;
} 

Если я наберу

abc

или

abc(ctrl+z)

Программа будет иметь такие же выходы:

ABC


// 2nd piece of Code
#include<stdio.h>

int main(void)
{
    int x;
    while(scanf("%d",&x) != EOF)
    {
        /*Ctrl + z + Enter*/
        printf("x=%d\n",x);
    }
    return 0;
}

Если я наберу

123

Программа выведет:

х = 123

В противном случае, если я наберу

123(ctrl+z)

Программа будет иметь бесконечный вывод:

* * Тысяча тридцать-семь х = 123
* +1039 * х = 123

х = 123

х = 123

...

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

getchar() возвращает значение символа, преобразованного в unsigned char или EOF в случае ошибки.

Ошибка может быть «конец файла» или что-то еще; обычно (для getchar()) программисту нет дела до ошибки, просто ошибка произошла.


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

Как и для getchar(), ошибка может быть «концом файла» или чем-то еще. В частности, чтение меньше числа % не является ошибкой .

Таким образом, вы можете предпочесть проверить правильное количество назначений, а не проверять на наличие ошибок в scanf()

#include <stdio.h>

int main(void) {
    int x;
    while (scanf("%d", &x) != 1) {
        /*Ctrl + z + Enter*/
        printf("x=%d\n", x);
    }
    return 0;
}
0 голосов
/ 31 октября 2018

Проблема в том, что в Windows EOF помещается во входной буфер как обычный символ (с закодированным значением 26).

При чтении посимвольно (например, getchar) это обрабатывается библиотекой времени выполнения Windows. Но это не работает так с scanf, потому что когда scanf анализирует ввод, это похоже на другой символ. И, как не цифра, это недопустимый символ для формата "%d", что приводит к вашему scanf вызову для возврата 0 вместо EOF (так как он не анализируется форматом).

Один из способов решить эту проблему - нажать последовательность Ctrl-Z на новой строке.

Другой (и более надежный) способ решить эту проблему - проверить, что scanf возвращает количество форматов, которые у вас есть в строке. В вашем случае вы должны сравнить с 1 (так как у вас есть один спецификатор формата).

...