Это мой C исходный код.
Когда я собираю его в Ubuntu, он начинает получать символы, но я не знаю, как завершить программу, поскольку она не заканчивается вводом ENTERили возвратом каретки.
Что означает EOF? Как я могу вызвать это?
Этот источник также есть в книге Денниса Ритчи:
#include <stdio.h>
/* count digits, white space, others */
main ()
{
int c, i, nwhite, nother;
int ndigit[10];
nwhite = nother = 0;
for (i = 0; i < 10; ++i)
ndigit[i] = 0;
while ((c = getchar ()) != EOF)
if (c >= '0' && c <= '9')
++ndigit[c - '0'];
else if (c == ' ' || c == '\n' || c == '\t')
++nwhite;
else
++nother;
printf ("digits =");
for (i = 0; i < 10; ++i)
printf (" %d", ndigit[i]);
printf (", white space = %d, other = %d\n", nwhite, nother);
}
command-line
c
stackprogramer
источник
источник
-1
является эквивалентом EOF. Он определен/usr/include/stdio.h
как макроконстанция-1
качестве ввода не работает :)Ответы:
Tl; др
Как правило, вы можете «запустить EOF» в программе, запущенной на терминале нажатием клавиши CTRL+ Dсразу после последней очистки ввода.
EOF означает конец файла.
«Запуск EOF» в данном случае примерно означает «информирование программы о том, что ввод больше не будет отправлен».
В этом случае, так
getchar()
как вернет отрицательное число, если ни один символ не прочитан, выполнение прекращается.Но это относится не только к вашей конкретной программе, это относится ко многим различным инструментам.
В общем, «запуск EOF» может быть выполнен нажатием клавиши CTRL+ Dсразу после последнего сброса ввода (т. Е. Путем отправки пустого ввода).
Например с
cat
:При нажатии CTRL+ Dпроисходит то, что ввод, введенный с момента последнего сброса ввода, сбрасывается; когда это пустой вход,
read()
системный вызов, вызванный из STDIN программы0
,getchar()
возвращает отрицательное число (-1
в библиотеке GNU C), и это, в свою очередь, интерпретируется как EOF 1 .1 - /programming//a/1516177/4316166
источник
TL; DR : EOF - это не символ, это макрос, используемый для оценки отрицательного возврата функции чтения ввода. Можно использовать Ctrl+, Dчтобы отправить
EOT
символ, который заставит функцию вернуть-1
Каждый программист должен RTFM
Давайте обратимся к «Справочному руководству CA» Harbison and Steele, 4-е изд. с 1995 г., стр. 317:
По сути
EOF
это не символ, а скорее целое значение реализуется вstdio.h
представлять-1
. Таким образом, ответ Коса является правильным, но речь идет не о получении «пустого» ввода. Важно отметить, что здесь EOF служит для сравнения возвращаемого значения (ofgetchar()
), а не для обозначения фактического символа. Поддержки,man getchar
которые:Рассмотрим
while
цикл - его основная цель - повторить действие, если условие в скобках выполнено . Посмотри снова:По сути, он говорит, что продолжайте делать что-то, если
c = getchar()
возвращает успешный код (0
или выше; кстати, это обычное дело, попробуйтеecho $?
выполнить успешную команду, затем не удалосьecho $?
и посмотрите числа, которые они возвращают). Поэтому, если мы успешно получим символ и добавим C, возвращенный код состояния будет равен 0, а ошибка - -1.EOF
определяется как-1
. Поэтому, когда-1 == -1
возникает условие , цикл останавливается. И когда это произойдет? Когда нет больше персонажа, чтобы получить, когдаc = getchar()
не удается. Вы могли бы написать,while ((c = getchar ()) != -1)
и это все еще будет работатьКроме того, давайте вернемся к фактическому коду, вот выдержка из
stdio.h
Коды ASCII и EOT
Хотя символ EOF не является действительным символом, тем не менее, существует символ
EOT
(Конец передачи), который имеет десятичное значение ASCII 04; он связан с ярлыком Ctrl+ D(представлен также как метасимвол^D
). Характер окончания передачи использовался для обозначения закрытия потока данных в обратном направлении, когда компьютеры использовались для контроля телефонных соединений, отсюда и название «конец передачи».Таким образом, можно отправить это значение ascii в программу следующим образом, обратите внимание на то,
$'\04'
что является EOT:Таким образом, мы можем сказать, что он существует, но это не для печати
Примечание
Мы часто забываем, что в прошлом компьютеры не были такими универсальными - дизайнеры должны использовать каждую доступную клавиатуру. Таким образом, отправка
EOT
символа с помощью CtrlD по-прежнему является «отправкой символа», в отличие от ввода прописной буквы A, ShiftA, вы все равно заставляете компьютер вводить данные с помощью доступных клавиш. Таким образом, EOT - это реальный символ в том смысле, что он исходит от пользователя, он читается компьютером (хотя не для печати, не виден людьми), он существует в компьютерной памятиКомментарий Byte Commander
Да, совершенно верно, потому
/dev/null
что нет никакого действительного символа, который нужно прочитать, следовательно, онc = getchar()
вернет-1
код, и программа сразу же закроется. Снова команда не возвращает EOF. EOF - это просто постоянная переменная, равная -1, которую мы используем для сравнения кода возврата функции getchar .EOF
не существует как символ, это просто статическое значение внутриstdio.h
.Демо-версия:
Еще один гвоздь в гробу
Иногда пытаются доказать, что EOF - это символ с кодом, подобным этому:
Проблема в том, что тип данных char может иметь значение со знаком или без знака. Кроме того, они являются наименьшим адресуемым типом данных, что делает их очень полезными в микроконтроллерах, где память ограничена. Таким образом, вместо декларации
int foo = 25;
обычно можно увидеть в микроконтроллерах с небольшим объемом памятиchar foo = 25;
или что-то подобное. Кроме того, символы могут быть подписаны или не подписаны .Можно проверить, что размер в байтах с программой, как это:
Какой именно смысл? Дело в том, что EOF определяется как -1, но тип данных char может печатать целочисленные значения .
OK . , .то, что если мы попытаемся напечатать char как строку?
Очевидно, это ошибка, но, тем не менее, ошибка скажет нам кое-что интересное:
Шестнадцатеричные значения
Печать EOF в виде шестнадцатеричного значения дает
FFFFFFFF
16-битное (8-байтовое) значение, два комплимента a-1
.Выход:
Еще одна любопытная вещь происходит со следующим кодом:
Если нажать Shift+ A, мы получим шестнадцатеричное значение 41, очевидно, такое же, как в таблице ASCII. Но для Ctrl+ Dмы
ffffffff
снова получаем возвращаемое значение,getchar()
хранящееся вc
.Обратитесь к другим языкам
Обратите внимание, что другие языки избегают этой путаницы, потому что они работают с оценкой состояния завершения функции, а не сравнивают ее с макросом. Как читать файл в Java?
Как насчет питона?
источник
/dev/null
, это также должно вернуть EOF, верно? Или что я получу там?EOF обозначает конец файла . Хотя я не знаю, как вызвать следующий символ, вы можете запустить следующую программу через конвейер файла, который в конце посылает сигнал EOF :
где
a.out
твой скомпилированный источникисточник
read()
возвращаемые данные0
, которые будут очищены пустыми (syscall), вернутся , что интерпретируется как EOF: stackoverflow.com/a/1516177/4316166