Это мой исходный код на 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);
}
можно обычно "инициировать EOF" в программе, работающей в терминале с CTRL + нажатие клавиши D прямо после последнего входного сброса.
<час>, Что означает EOF? Как я могу инициировать его?
EOF означает Конец Файла.
"Инициирование EOF" в этом случае примерно означает "делать программу знающей, что более вход не будет отправлен".
В этом случае, с тех пор getchar()
возвратит отрицательное число, если никакой символ не будет считан, выполнение завершается.
, Но это не только относится к Вашей определенной программе, она относится ко многим различным инструментам.
В общем "инициировании EOF" может быть сделан с CTRL + нажатие клавиши D прямо после последнего входного сброса (т.е. путем отправки пустого входа).
, Например, с cat
:
% cat >file # Hit ENTER
foo # Hit ENTER and CTRL+D
%
, Что происходит под капотом при ударе CTRL + D - то, что вход, введенный начиная с последнего входного сброса, сбрасывается; когда это, оказывается, пустой вход read()
, syscall обратился к возвратам STDIN программы 0
, getchar()
возвраты отрицательное число (-1
в библиотеке GNU C), и это в свою очередь интерпретируется как EOF <глоток> 1 глоток>.
EOF обозначает конец файла . В то время как я не знаю, как инициировать следующий символ, можно запустить следующую программу посредством передачи по каналу файла, который отправляет сигнал EOF в конце:
echo "Some sample text" | ./a.out
, где a.out
Ваш скомпилированный источник
TL; DR: EOF не является символом, это - макрос, используемый для оценки отрицательного возврата читающей вход функции. Можно использовать Ctrl+D для отправки EOT
символ, который вызовет функциональный возврат -1
Каждый программист должен прочитайте руководство
Давайте обратимся к "C Справочник", Harbison и Steele, 4-м редактором с 1995, страницей 317:
Отрицательный целочисленный EOF является значением, которое не является кодированием "реального символа"... Например, fget (разделяют 15.6) возвращает EOF когда в конце, потому что нет никакого "реального символа", чтобы быть считанным.
По существу EOF
не символ, а скорее целочисленное значение, реализованное в stdio.h
представить -1
. Таким образом ответ Коса корректен насколько это идет, но это не о получении "пустого" входа. Важное примечание - то, что здесь EOF служит возвращаемым значением ( getchar()
) сравнение, для не выражения фактического символа. man getchar
поддержки, что:
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
fgetc (), getc () и getchar () возвращают символьное чтение как неподписанный символьный бросок к интервалу или EOF на конце файла или ошибки.
добирается (), и fgets () возвращают s на успехе и ПУСТОЙ УКАЗАТЕЛЬ на ошибке или когда конец файла происходит, в то время как никакие символы не были считаны.
ungetc () возвращает c на успехе или EOF на ошибке.
Рассмотрите while
цикл - его основная цель состоит в том, чтобы повторить действие, если условие в скобках верно. Посмотрите снова:
while ((c = getchar ()) != EOF)
Это в основном говорит, продолжают делать материал если c = getchar()
возвращает успешный код (0
или выше; это - общая вещь между прочим, попытайтесь выполнить успешную команду, затем echo $?
и затем отказавший echo $?
и посмотрите числа, которые они возвращают). Таким образом, если мы успешно получаем символ и присваиваемся к C, возвратился, код состояния 0, отказавший-1. EOF
определяется как -1
. Поэтому, когда условие -1 == -1
происходит, остановки циклов. И когда это произойдет? Когда больше нет символа для получения, когда c = getchar()
сбои. Вы могли записать while ((c = getchar ()) != -1)
и это все еще работало бы
Кроме того, давайте вернемся к фактическому коду, вот выборка от stdio.h
/* End of file character.
Some things throughout the library rely on this being -1. */
#ifndef EOF
# define EOF (-1)
#endif
Коды ASCII и EOT
Хотя символ EOF не является фактическим символом, однако, там существует EOT
(Конец Передачи) символ, который имеет десятичное значение ASCII 04; это связано с ярлыком Ctrl+D (представленный также как метасимвол ^D
). Конец передачи chracter раньше показывал закрытие потока магистрали данных назад, когда компьютеры использовались для управления телефонными соединениями, следовательно "конец передачи" именование.
Таким образом, возможно отправить то значение ASCII в программу как так, отметьте $'\04'
который является EOT:
skolodya@ubuntu:$ ./a.out <<< "a,b,c $'\04'"
digits = 1 0 0 0 1 0 0 0 0 0, white space = 2, other = 9
Таким образом мы можем сказать, что это делает существует, но это не является печатаемым
Примечание стороны
Мы часто забываем, что в прошлых компьютерах не были так же универсальны - разработчики должны использовать каждую доступную клавишу на клавиатуре. Таким образом, отправка EOT
символ с CtrlD все еще "отправляет символ", мало чем отличаясь от ввода капитала A, ShiftA, Вы все еще делаете, дают компьютеру вход с доступными ключами. Таким образом EOT является реальным символом в некотором смысле, что он действительно прибывает от пользователя, это читаемо компьютером (хотя не печатаемый, не видимый людьми), он существует в памяти компьютера
Комментарий Командующего байта
При попытке читать из/dev/null, который должен возвратить EOF также, правильно? Или что я получаю там?
Да, точно право, потому что в /dev/null
нет никакого фактического символа, который будет считан, следовательно это c = getchar()
возвратится -1
код и программа выйдут сразу же. Команда Again не возвращает EOF. EOF является просто постоянной переменной, равной-1, который мы используем для сравнения кода возврата функции getchar. EOF
не существует как символ, это - просто статическое значение внутри stdio.h
.
Демонстрация:
# cat /dev/null shows there's no readable chars
DIR:/xieerqi
skolodya@ubuntu:$ cat /dev/null | cat -A
# Bellow is simple program that will open /dev/null for reading. Note the use of literal -1
DIR:/xieerqi
skolodya@ubuntu:$ cat readNull.c
#include<stdio.h>
void main()
{
char c;
FILE *file;
file = fopen("/dev/null", "r");
if (file)
{
printf ("Before while loop\n");
while ((c = getc(file)) != -1)
putchar(c);
printf("After while loop\n");
fclose(file);
}
}
DIR:/xieerqi
skolodya@ubuntu:$ gcc readNull.c -o readNull
DIR:/xieerqi
skolodya@ubuntu:$ ./readNull
Before while loop
After while loop
Еще один гвоздь в крышку гроба
Иногда это предпринято, чтобы быть доказанным, что EOF является символом с кодом как это:
#include <stdio.h>
int main(void)
{
printf("%c", EOF);
return 0;
}
Проблема с этим состоит в том, что тип данных char может быть или неподписанным значением со знаком. Кроме того, они - самый маленький адресуемый тип данных, который делает их очень очень полезными в микроконтроллерах, где память ограничена. Таким образом вместо объявления int foo = 25;
распространено видеть в микроконтроллерах с маленькой памятью char foo = 25;
или что-то подобное. Кроме того, символы могут быть подписаны или не подписаны.
Можно было проверить что размер в байтах с программой как это:
#include <stdio.h>
int main(void)
{
printf("Size of int: %lu\n",sizeof(int));
printf("Sieze of char: %lu\n",sizeof(char));
//printf("%s", EOF);
return 0;
}
skolodya@ubuntu:$ ./EOF
Size of int: 4
Sieze of char: 1
Какова точно точка? Дело в том, что EOF определяется как-1, но тип данных char может распечатать целочисленные значения.
Хорошо.. .so, что, если мы пытаемся распечатать символ как строку?
#include <stdio.h>
int main(void)
{
printf("%s", EOF);
return 0;
}
Очевидно, ошибка, но тем не менее, ошибка скажет нам что-то интересное:
skolodya@ubuntu: $ gcc EOF.c-o EOF
EOF.c: В 'основной' функции: EOF.c:4:5: предупреждение: формат ‘%s’ ожидает аргумент типа ‘символ *’, но аргумент 2 имеет тип 'интервал' [-Wformat =] printf ("%s", EOF);
Шестнадцатеричные значения
При печати EOF, поскольку шестнадцатеричное значение дает FFFFFFFF
, (8-байтовое) значение на 16 битов, комплимент two a -1
.
#include <stdio.h>
int main(void)
{
printf("This is EOF: %X\n", EOF);
printf("This is Z: %X\n",'Z');
return 0;
}
Вывод:
DIR:/xieerqi
skolodya@ubuntu:$ ./EOF
This is EOF: FFFFFFFF
This is Z: 5A
Другая любопытная вещь происходит со следующим кодом:
#include <stdio.h>
int main(void)
{
char c;
if (c = getchar())
printf ("%x",c);
return 0;
}
Если Вы нажимаете Shift + A, мы получаем шестнадцатеричное значение 41, очевидно, то же как в таблице ASCII. Но для Ctrl + D, мы имеем ffffffff
, снова - возвращаемое значение getchar()
сохраненный в c
.
DIR:/xieerqi
skolodya@ubuntu:$ gcc EOF.c -o ASDF.asdf
DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf
A
41
DIR:/xieerqi
skolodya@ubuntu:$ ./ASDF.asdf
ffffffff
Обратитесь к другим языкам
Заметьте, что другой язык избегает этого беспорядка, потому что они воздействуют на оценку функционального статуса выхода, не сравнивая его с макросом. Как каждый читает файл в Java?
File inputFile = new File (filename);
Scanner readFile = new Scanner(inputFile);
while (readFile.hasNext())
{ //more code bellow }
Как насчет Python?
with open("/etc/passwd") as file:
for line in file:
print line