Символ новой строки представлен "\n"
в коде C. Есть ли эквивалент для символа конца файла (EOF)?
Представлять EOF в коде C?
Ответы (11)
EOF не является символом (в большинстве современных операционных систем). Это просто условие, которое применяется к файловому потоку при достижении конца потока. Путаница возникает из-за того, что пользователь может сигнализировать EOF для ввода в консоль, введя специальный символ (например, Control-D в Unix, Linux, и др.), но этот символ не видно работающей программе, оно перехватывается операционной системой, которая, в свою очередь, сигнализирует процессу EOF.
Примечание: в некоторых очень старых операционных системах EOF был символом, например. Control-Z в CP/M, но это был грубый хак, чтобы избежать накладных расходов на сохранение фактической длины файлов в каталогах файловой системы.
getchar()
et al является либо допустимым символом, либо отдельным кодом, EOF, который не является кодом допустимого символа. EOF
, которое расширяется до целочисленного константного выражения с типом int
и отрицательным значением, которое возвращается несколькими функциями для указания конца файла, то есть больше никаких входных данных из потока;' и 'функция fgetc
получает [следующий] символ как unsigned char
, преобразованный в int
". Таким образом, в любой системе, где sizeof(char) != sizeof(int)
, EOF отличается от любого char
.
- person Jonathan Leffler; 12.09.2012
copy
при использовании с параметром /a (режим ASCII) добавит код символа EOF в конец добавляемых файлов. Точно так же команда type
подчиняется символам EOF, которые встречаются в текстовых файлах. Является пережитком MS-DOS. ‹/Урок истории›
- person vercellop; 22.05.2018
EOF
не является персонажем. Этого не может быть: (двоичный) файл может содержать любой символ. Предположим, у вас есть файл с постоянно увеличивающимися байтами, начиная с 0 1 2 3 ... 255 и еще раз 0 1 ... 255, всего 512 байт. Какой бы из этих 256 возможных байтов вы ни выбрали EOF
, файл будет обрезан.
Вот почему getchar()
и др. вернуть int
. Диапазон возможных возвращаемых значений — это значения, которые может иметь char
, плюс подлинное значение int
EOF
(определенное в stdio.h
). По этой же причине преобразование возвращаемого значения в char
до проверки EOF
не сработает.
Обратите внимание, что некоторые протоколы имеют "символы" EOF. В ASCII есть «Конец текста», «Конец передачи», «Конец блока передачи» и «Конец среды». В других ответах упоминались старые ОС. Я сам ввожу ^D в Linux и ^Z в консолях Windows, чтобы перестать вводить программы. (Но файлы, прочитанные через конвейеры, могут иметь символы ^D и ^Z в любом месте и сообщать об окончании EOF только тогда, когда в них заканчиваются байты.) Строки C заканчиваются символом '\0'
, но это также означает, что они не могут содержать персонаж '\0'
. Вот почему все функции нестроковых данных C работают с использованием массива char
(чтобы содержать данные) и size_t
(чтобы знать, где заканчиваются данные).
Изменить: стандарт C99 §7.19.1.3 гласит:
Макросы [...]
EOF
, которые расширяются до целочисленного константного выражения с типомint
и отрицательным значением, которое возвращается несколькими функциями для указания конца -of-file, то есть больше никаких входных данных из потока;
((charVar = getchar()) == EOF)
, увидят некорректное поведение. Вы говорите, что они могут получить преждевременный, ложный EOF, когда они прочитают это значение char
, которое оказывается равным EOF
при повышении до int
, вместо того, чтобы зацикливаться навсегда, потому что никакое char
никогда не будет равно EOF
. Решение все то же: ((intVar = getchar()) == EOF)
- person aib; 13.09.2012
EOF
не равно значению char
. В самом деле, даже если в реализации используется один и тот же тип char
и int
, они по-прежнему являются разными типами для стандарта и тех, которые ему соответствуют.
- person aib; 13.09.2012
unsigned char
, преобразованный в int
, поэтому он должен иметь неотрицательное значение, которое не может равняться EOF
, поскольку EOF
отрицательно. Однако одно из определений «символа» в стандарте C — это «битовое представление, умещающееся в байте». И многие люди обрабатывают символы, используя тип char
, который может быть подписан. (На самом деле, fgets
принимает char *
.) Тогда возможно иметь char x
, значение которого равно EOF
, но которое можно корректно распечатать с помощью fputc
и других функций.
- person Eric Postpischil; 20.07.2019
EOF
, используя возвращаемое значение из таких функций, как fgetc
, которая возвращает символ как unsigned char
, преобразованный в int
, или EOF
. Это будет работать во всех, кроме экзотических гипотетических реализациях C, обсуждаемых в ссылке, которую я предоставил. (Чтобы написать код даже для этих реализаций, используйте функцию feof
.) Но не следует предполагать, что значение char
не равно EOF
.
- person Eric Postpischil; 20.07.2019
Нет. EOF — это не символ, а состояние дескриптора файла.
Хотя в кодировке ASCII есть управляющие символы, обозначающие конец данных, в целом они не используются для обозначения конца файлов. Например, EOT (^D), что в некоторых случаях почти означает то же самое.
Когда стандартная библиотека C использует целое число со знаком для возврата символов и использует -1 для конца файла, это на самом деле просто сигнал, указывающий, что произошла ошибка. У меня нет доступного стандарта C, но процитирую SUSv3:
Если индикатор конца файла для потока установлен или если поток находится в конце файла, должен быть установлен индикатор конца файла для потока, а функция fgetc() должна возвращать EOF. Если возникает ошибка чтения, должен быть установлен индикатор ошибки для потока, функция fgetc() должна возвращать EOF и должна устанавливать errno, чтобы указать на ошибку.
Я прочитал все комментарии. Интересно заметить, что происходит, когда вы распечатываете это:
printf("\nInteger = %d\n", EOF); //OUTPUT = -1
printf("Decimal = %d\n", EOF); //OUTPUT = -1
printf("Octal = %o\n", EOF); //OUTPUT = 37777777777
printf("Hexadecimal = %x\n", EOF); //OUTPUT = ffffffff
printf("Double and float = %f\n", EOF); //OUTPUT = 0.000000
printf("Long double = %Lf\n", EOF); //OUTPUT = 0.000000
printf("Character = %c\n", EOF); //OUTPUT = nothing
Как мы видим здесь, EOF НЕ является символом (чем бы то ни было).
EOF
не является числом с плавающей запятой, двойным или длинным двойным числом, поэтому очевидно, что печать его как типа с плавающей запятой не работает.
- person phuclv; 22.08.2020
Я думаю, что это может варьироваться от системы к системе, но один из способов проверки - просто использовать printf
#include <stdio.h>
int main(void)
{
printf("%d", EOF);
return 0;
}
Я сделал это в Windows, и -1
было напечатано на консоли. Надеюсь это поможет.
Значение EOF нельзя спутать ни с каким реальным символом.
Если a= getchar()
, то мы должны объявить a
достаточно большим, чтобы вместить любое значение, которое возвращает getchar()
. Мы не можем использовать char
, так как a
должно быть достаточно большим, чтобы содержать EOF в дополнение к символам.
a
, трудно понять. Я отредактировал ваш пост, чтобы внести немного ясности.
- person Luke Taylor; 27.03.2016
Ответ НЕТ, но...
Вы можете запутаться из-за поведения fgets()
Из http://www.cplusplus.com/reference/cstdio/fgets/ :
Считывает символы из потока и сохраняет их как строку C в str до тех пор, пока не будет прочитано (num-1) символов или не будет достигнут либо перевод строки, либо конец файла, в зависимости от того, что произойдет раньше.
Символ EOF
, распознаваемый интерпретатором команд в Windows (и MSDOS, и CP/M), равен 0x1a (десятичное число 26, также известное как Ctrl+Z или SUB).
Его все еще можно использовать сегодня, например, для обозначения конца удобочитаемого заголовка в двоичном файле: если файл начинается с "Some description\x1a"
, пользователь может вывести содержимое файла на консоль с помощью команды TYPE
, и дамп остановится на EOF
персонаж, т.е. напечатать некоторое описание и остановиться, вместо того, чтобы продолжать с последующим мусором.
Есть константа EOF
типа int, найденная в stdio.h. Ни в одном стандарте не существует эквивалентного символьного литерала.
Я много исследовал сигнал EOF. В книге Денниса Ритчи «Программирование на C» он впервые встречается при вводе команд putchar() и getchar(). Это в основном отмечает конец ввода строки символов.
Например. Давайте напишем программу, которая ищет два числовых входа и печатает их сумму. Вы заметите, что после каждого числового ввода вы нажимаете Enter, чтобы отметить сигнал о завершении действия ввода. Но при работе со строками символов Enter читается как просто еще один символ ['\n': символ новой строки]. Чтобы отметить прекращение ввода, введите ^Z (Ctrl + Z на клавиатуре) в совершенно новой строке, а затем введите. Это сигнализирует о выполнении следующих строк команды.
#include <stdio.h>
int main()
{
char c;
int i = 0;
printf("INPUT:\t");
c = getchar();
while (c != EOF)
{
++i;
c = getchar();
};
printf("NUMBER OF CHARACTERS %d.", i);
return 0;}
Выше приведен код для подсчета количества символов, включая символы '\n' (новая строка) и '\t' (пробел). Если вы не хотите считать символы новой строки, сделайте следующее:
#include <stdio.h>
int main()
{
char c;
int i = 0;
printf("INPUT:\t");
c = getchar();
while (c != EOF)
{
if (c != '\n')
{
++i;
}
c = getchar();
};
printf("NUMBER OF CHARACTERS %d.", i);
return 0;}.
СЕЙЧАС ГЛАВНОЕ ДУМАЕМ, КАК ДАТЬ ВВОД. ЭТО ПРОСТО: напишите всю историю, которую хотите, затем перейдите на новую строку и введите ^Z, а затем введите еще раз.