¿Representando EOF en código C?


El carácter de nueva línea está representado por "\n" en el código C. ¿Hay un equivalente para el carácter de fin de archivo (EOF)?

Author: static_rtti, 2012-09-12

10 answers

EOF no es un carácter (en la mayoría de los sistemas operativos modernos). Es simplemente una condición que se aplica a una secuencia de archivos cuando se alcanza el final de la secuencia. La confusión surge porque un usuario puede señalar EOF para la entrada de consola escribiendo un carácter especial (por ejemplo Control-D en Unix, Linux, et al ), pero este carácter no es visto por el programa en ejecución, es capturado por el sistema operativo que a su vez señala EOF al proceso.

Nota: en algunas operaciones muy antiguas systems EOF era un carácter, por ejemplo Control-Z en CP/M, pero esto era un truco crudo para evitar la sobrecarga de mantener las longitudes de archivo reales en los directorios del sistema de archivos.

 51
Author: Paul R,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-10 22:36:18

No. EOF no es un carácter, sino un estado del filehandle.

Si bien hay caracteres de control en el conjunto de caracteres ASCII que representan el final de los datos, estos no se utilizan para señalar el final de los archivos en general. Por ejemplo EOT (^D) que en algunos casos casi señala lo mismo.

Cuando la biblioteca estándar de C usa entero firmado para devolver caracteres y usa -1 para el final del archivo, esto es en realidad solo la señal para indicar que ocurrió un error. Me no tiene el estándar C disponible, pero citando SUSv3:

Si se establece el indicador de fin de archivo para la secuencia, o si la secuencia está al final del archivo, se establecerá el indicador de fin de archivo para la secuencia y fgetc() devolverá EOF. Si se produce un error de lectura, se establecerá el indicador de error para la secuencia, fgetc() devolverá EOF, y establecerá errno para indicar el error.

 7
Author: pmakholm,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 13:58:01

EOF no es un personaje. No puede ser: Un archivo (binario) puede contener cualquier carácter. Supongamos que tiene un archivo con bytes cada vez mayores, yendo 0 1 2 3 ... 255 y otra vez 01 ... 255, para un total de 512 bytes. Cualquiera de esos 256 bytes posibles que considere EOF, el archivo se cortará.

Por eso getchar() et al. devuelve un int. El rango de posibles valores de retorno son aquellos que un char puede tener, más un verdadero int valor EOF (definido en stdio.h). Por eso también convertir el valor devuelto a un char antes de comprobar EOF no funcionará.

Tenga en cuenta que algunos protocolos tienen caracteres "EOF"."ASCII tiene "Fin de Texto", "Fin de la Transmisión", "Fin del Bloque de Transmisión" y "el Final del Medio". Otras respuestas han mencionado al viejo OS'es. Yo mismo introduzco ^D en Linux y ^Z en las consolas de Windows para dejar de dar entrada a los programas. (Pero los archivos leídos a través de tuberías pueden tener caracteres ^D y ^Z en cualquier lugar y solo señalan EOF cuando se quedan sin bytes.) C las cadenas están terminadas con el carácter '\0', pero eso también significa que no pueden contener el carácter '\0'. Es por eso que todas las funciones de datos sin cadena de C funcionan usando una matriz char (para contener los datos) y una size_t (para saber dónde terminan los datos).

Editar: El estándar C99 §7.19.1.3 establece:

Las macros son [...]
EOF
que se expande a una expresión constante entera, con tipo int y un valor negativo, que es devuelto por varios funciones para indica fin del archivo , es decir, no más entrada de un flujo;

 5
Author: aib,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 15:25:34

He leído todos los comentarios. Es interesante notar lo que sucede cuando imprimes esto:

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

Como podemos ver aquí, EOF NO es un carácter (en absoluto).

 2
Author: Carlos W. Mercado,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-16 15:28:53

El carácter EOF reconocido por el intérprete de comandos en Windows (y MSDOS, y CP/M) es 0x1a (decimal 26, aka Ctrl+Z aka SUB)

Todavía se puede usar hoy en día, por ejemplo, para marcar el final de un encabezado legible por humanos en un archivo binario: si el archivo comienza con "Alguna descripción\x1a", el usuario puede volcar el contenido del archivo a la consola utilizando el comando TYPE y el volcado se detendrá en el carácter EOF , es decir, imprimir Alguna descripción y detenerse, en lugar de continuar con la basura que sigue.

 1
Author: Axel Rietschin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-01 20:00:57

El valor de EOF no se puede confundir con ningún carácter real.

Si a= getchar(), entonces debemos declarar a lo suficientemente grande como para contener cualquier valor que getchar() devuelve. No podemos usar char ya que a debe ser lo suficientemente grande como para contener EOF además de caracteres.

 1
Author: Harsh Vardhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-27 14:01:55

La respuesta es NO, pero...

Puede confundirse debido al comportamiento de fgets()

De http://www.cplusplus.com/reference/cstdio/fgets/ :

Lee caracteres de stream y los almacena como una cadena C en str hasta que se hayan leído los caracteres (num-1) o se alcance una nueva línea o el final del archivo, lo que ocurra primero.

 1
Author: betontalpfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-23 10:50:44

Esto es dependiente del sistema pero a menudo -1. Ver aquí

 0
Author: onoma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 13:42:40

Existe la constante EOF del tipo int, que se encuentra en stdio.h. No hay un literal de carácter equivalente especificado por ningún estándar.

 0
Author: Lundin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 13:42:51

Creo que puede variar de un sistema a otro, pero una forma de verificar sería simplemente usar printf

#include <stdio.h>
int main(void)
{
    printf("%d", EOF);
    return 0;
}

Hice esto en Windows y -1 se imprimió en la consola. Espero que esto ayude.

 0
Author: Keith Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-12 13:43:40