Прежде всего, давайте проясним одну вещь: не существует такого понятия, как символ EOF
. EOF
не существует как символ, вы не сможете ввести EOF
или прочитать EOF
. EOF
— это просто произвольная целочисленная константа, определенная библиотекой абстракция, которая используется библиотечными функциями, чтобы сигнализировать о достижении конца файла или о возникновении ошибки. Вот и все.
Если вы хотите убедиться, что то, что вы делаете, имеет смысл, взгляните на scanf
справочная страница:
RETURN VALUE
On success, these functions return the number of input items
successfully matched and assigned; this can be fewer than provided
for, or even zero, in the event of an early matching failure.
The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs.
EOF is also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set to
indicate the error.
Читая выше, становится ясно, что scanf
не только возвращает EOF
при достижении конца файла. Кроме того, scanf
может возвращать 0
, если ошибки не произошло, но совпадения не произошло, и в этом случае также следует прекратить чтение.
Что вы хотите сделать в этом случае, так это использовать простой цикл for
и проверить, вернул ли scanf
1
, что является единственным приемлемым для вас значением. Если нет, то либо достигнут конец файла, либо произошла ошибка, либо ввод не соответствует строке формата: проверьте ошибку и действуйте соответственно. Не сжимайте всю логику проверки ошибок внутри условия while
, это просто сбивает с толку и трудно понять правильно.
Вот рабочий пример, проверка ошибок, вероятно, даже больше, чем вам действительно нужно, но это просто для ясности.
size_t read_ints_from_stdin(int array[], size_t max_array_size) {
size_t i;
for (i = 0; i < max_array_size; i++) {
int res = scanf("%d", &array[i]);
if (res != 1) {
if (res == EOF) {
if (feof(stdin)) {
// End of file reached, not an error.
} else {
// Real error, print that out to stderr.
perror("scanf failed");
}
} else {
// Input matching failure.
fputs("Input does not match requested format.\n", stderr);
}
break;
}
}
return i;
}
Также обратите внимание на использование size_t
там, где это необходимо, вместо int
. Вы не хотите, чтобы в конечном итоге возникали ошибки, возникающие из-за отрицательных значений при работе с размерами или индексами.
person
Marco Bonelli
schedule
29.07.2020
EOF
определяется в stdio.h (обычно это-1
). В Linuxctrl+d
сигнализирует EOF, а в Windows этоctrl+z
для стандартного ввода процесса через оболочку. ты сделал что-то из этого? - person nor   schedule 29.07.2020scanf
вернет 0 и оставит неверный символ в потоке, поэтому он никогда не вернет EOF. Я предлагаю== 1
вместо!= EOF
здесь. - person n. 1.8e9-where's-my-share m.   schedule 29.07.2020