У меня есть два кода, чтобы проверить, как две функции ввода-вывода консоли, 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)
The program will have the same outputs:
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
The program will output:
x=123
В противном случае, если я наберу
123(ctrl+z)
The program will have an infinite output:
x=123
x=123
x=123
x=123
...
Это printf("x=%\n",x);
-> printf("x=%d\n",x);
@ Ахал Ой! виноват! Я поправил.
С scanf
вы обычно проверяете, показывает ли возвращаемое значение количество преобразований, равное ожидаемому, здесь вам следует сравнить с 1
. Если это не 1, значит, значение не было прочитано.
Проблема в том, что в Windows EOF
помещается во входной буфер как обычный символ (с закодированным значением 26
).
При чтении посимвольно (например, с getchar
) это обрабатывается библиотекой времени выполнения Windows. Но с scanf
это не работает, потому что, когда scanf
анализирует ввод, он похож на другой символ. И поскольку это не цифра, это недопустимый символ для формата "%d"
, что приводит к тому, что ваш вызов scanf
возвращает 0
вместо EOF
(поскольку он не анализируется форматом).
Один из способов решить эту проблему - нажать последовательность Ctrl-Z на отдельной новой строке.
Другой (и более надежный) способ решить эту проблему - проверить, что scanf
возвращает количество форматов, которые у вас есть в строке. В вашем случае вам следует сравнить с 1
(поскольку у вас есть один спецификатор формата).
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;
}
Функция
getchar
возвращаетint
. На самом деле это очень важно для сравненияEOF
.