Что такое EOF и как его запустить? [закрыто]

Это мой исходный код на 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);
}
12
задан 24 January 2016 в 19:19

3 ответа

Tl; доктор

можно обычно "инициировать 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 .

<час>

1 - https://stackoverflow.com/a/1516177/4316166

22
ответ дан 23 November 2019 в 03:31

EOF обозначает конец файла . В то время как я не знаю, как инициировать следующий символ, можно запустить следующую программу посредством передачи по каналу файла, который отправляет сигнал EOF в конце:

echo "Some sample text" | ./a.out

, где a.out Ваш скомпилированный источник

2
ответ дан 23 November 2019 в 03:31

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
4
ответ дан 23 November 2019 в 03:31

Другие вопросы по тегам:

Похожие вопросы: