У меня есть этот код:
#include <stdio.h>
int main(void) {
int d=0;
d = getchar();
printf("%d\n", d);
}
Выход:
^Z
-1
Насколько я понимаю, здесь могут произойти две вещи:
Есть ли еще варианты? Какой из двух правильный?
В этом случае значение все равно присваивается d. В вашем предыдущем примере сканирования этого не было.
@WeatherVane Большое спасибо! У меня только один дополнительный вопрос: когда я смотрю на таблицу ASCII, там написано, что 25 — это «конец среды», а 26 — «замена». Может быть, это 25, а не 26?





В этом есть две части:
getchar().Что делает getchar(), понятно:
Возвращает EOF (-1) в случае любого сбоя. Если сбой вызван концом файла, дополнительно устанавливается индикатор eof (см. feof() на стандартном вводе).
Что в этом случае делает консоль ОС (Windows):
^ZОбратите внимание, что сочетание клавиш Ctrl-Z (SUB) характерно для Windows, MS-DOS и до этого CP/M. В CP/M SUB использовался для расширения файлов до размеров, кратных 128 байтам (требование его примитивной файловой системы), поэтому для файлов, размер которых не кратен 128 байтам, он по сути обозначал конец файла. В Unix и Linux используется сочетание клавиш Ctrl-D (EOT — конец передачи), что, возможно, имеет больше смысла, но на самом деле ни то, ни другое не является концом файла, терминология происходит от рассмотрения stdin как потока «файла», что упрощает интерфейсы драйверов устройств и перенаправление.
Итак, система (Windows) рассматривает Ctrl-Z в консоли как инструкцию по вставке EOF во входной поток консоли, а getchar() возвращает EOF и устанавливает флаг EOF входного потока. Повторение ^Z (или любого символа) является специфичным для платформы побочным эффектом. getchar() на самом деле ничего не повторяет.
На самом деле это не конец потока, и ввод может возобновиться после вызова одного из rewind(), fsetpos(), fseek() или clearerr().
Также обратите внимание, что это строго поведение входного потока консоли. Если бы stdin был перенаправлен из файла, EOF был бы указан в истинном конце файла, и этот файл мог бы содержать символы Ctrl-Z (SUB), и они были бы возвращены getchar() как значение 26.
В качестве примечания: когда файл открывается в текстовом режиме в Windows, символ 26 обрабатывается так же, как и раньше, и чтение файла заканчивается на этом этапе.
Большое спасибо! Значит, именно Windows, а не getchar преобразует 26 в -1? Вы говорите: «Итак, система (Windows) рассматривает Ctrl-Z в консоли как инструкцию по вставке EOF в поток ввода консоли», означает ли это, что она вставляет -1 в поток ввода консоли?
@user394334 user394334 Я действительно говорю, что это «как если бы» EOF был вставлен в Steam. Точная базовая реализация может не делать именно этого. Это модель поведения, которая подходит для написания кода с использованием stdio. Если вам нужен больший контроль на более низком уровне, используйте API консоли Windows
Последний вопрос: Итак, после этого getchar просматривает поток и обнаруживает EOF, который Windows поместила в поток, и возвращает EOF, который теперь равен -1 (то есть getchar устанавливает его как -1?)?
@WeatherVane Я кое-что узнал. Но опять же, непечатаемый символ в середине текстового файла был бы необычным. Возможно, мне придется проверить свое утверждение о том, что это не вызывает EOF при перенаправлении на стандартный ввод.
Я проверил это, прежде чем оставить свой комментарий.
@user394334 user394334 кто знает? Это имеет значение? А разве это не то же самое, что и ваш предыдущий вопрос? Суть «модели» поведения в том, что она не обязательно должна быть внутренне точной. Ему просто нужно соответствовать любому внешне наблюдаемому поведению.
@user394334 user394334 не имеет значения, как это произойдет. В случае перенаправления ввода файла Crtl-Z или Ctrl-D отсутствуют (с учетом моего первого комментария).
Клиффорд, я предполагаю, что это сделано для того, чтобы сохранить совместимость с древними текстовыми файлами, существовавшими до NT. Конечно, 0x1A, вероятно, находится не в середине файла, а в конце, и желательно не читать его как символ (в любом случае это не текст).
^Z, который вы видите, не является входным значением: это эхо от обработчика клавиатуры, как и в случае с другими клавишами, которые вы нажимаете. Вариант 3:getchar()считывает значениеCtrl-Z26и преобразует его в флагEOF.