¿Representando EOF en código C?

9 minutos de lectura

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

  • La pregunta supone incorrectamente que “EOF” es un carácter, cuando en realidad es un condición. De hecho, si fueron un personaje, ya no sería el final, ¿verdad?

    – KerrekSB

    12 de septiembre de 2012 a las 13:43

  • No hay carácter EOF. EOF es un fuera de los límites valor utilizado para indicar una condición EOF. No es igual a ningún valor de carácter (como lo lee getc() et.al.)

    – salvaje

    12 de septiembre de 2012 a las 13:43

  • @Kerrek SB: tiene razón, pero tenga en cuenta que algunos sistemas operativos en el pasado en realidad tenían un carácter EOF que estaba incrustado en el archivo, por ejemplo, CP/M usó Control-Z para esto.

    – Pablo R.

    12 de septiembre de 2012 a las 13:49

  • Las preguntas respondidas como “la pregunta es “demasiado obvia” no son tan útiles como las respuestas que muestran amabilidad y brindan orientación. Esta pregunta sobre EOF y SOF me molestó hasta que profundicé en ella. Aquí hay un buen artículo que analiza este punto exacto y respuestas con más detalle con ejemplos de código… ruslanspivak.com/eofnotchar

    – Rich Lysakowski Doctorado

    12 ene a las 17:35

avatar de usuario
pablo r

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

Nota: en algunos sistemas operativos muy antiguos EOF era un carácter, por ejemplo, Control-Z en CP/M, pero esto fue un truco crudo para evitar la sobrecarga de mantener las longitudes reales de los archivos en los directorios del sistema de archivos.

  • El estándar C no garantiza que EOF no sea un personaje.

    –Eric Postpischil

    12 de septiembre de 2012 a las 14:58

  • @EricPostpischil: el estándar C garantiza (indirectamente) que el valor de retorno de getchar() et al es un carácter válido o un código distinto, EOF, que no es el código de un carácter válido. EOF que se expande a una expresión constante entera, con tipo int y un valor negativo, que es devuelto por varias funciones para indicar el final del archivo, es decir, no más entradas de una secuencia;‘ y ‘los fgetc la función obtiene [the next] personaje como un unsigned char convertido en un int‘. En cualquier sistema donde sizeof(char) != sizeof(int)por lo tanto, EOF es distinto de cualquier char.

    –Jonathan Leffler

    12/09/2012 a las 15:42


  • También tenga en cuenta que incluso hoy en Windows, Ctrl-Z en un archivo activará una condición EOF si se abre en modo de texto. Microsoft se toma muy en serio su retrocompatibilidad con CP/M.

    – Michael Burr

    13 de septiembre de 2012 a las 5:50


  • @Michael Burr: Dios mío, no sabía eso, así que, de alguna manera, no hemos llegado tan lejos de la era CP/M.

    – Pablo R.

    13 de septiembre de 2012 a las 6:08

  • @MichaelBurr: ¿Está seguro de que es Windows y no la implementación de stdio específica del compilador? AFAIK, Windows ni siquiera tiene una condición de “abierto en modo de texto”.

    – Ben Voigt

    2 de agosto de 2014 a las 5:23


avatar de usuario
aib

EOF no es un personaje. No puede ser: un archivo (binario) puede contener cualquier carácter. Suponga que tiene un archivo con bytes cada vez mayores, yendo 0 1 2 3 … 255 y una vez más 0 1 … 255, para un total de 512 bytes. Cualquiera de esos 256 bytes posibles que considere EOFel archivo se acortará.

Es por eso getchar() et al. devolver un int. El rango de posibles valores de retorno son aquellos que un char puede tener, además de un genuino int valor EOF (definido en stdio.h). Esa es también la razón por la que convertir el valor devuelto en un char antes de verificando para EOF no trabajará.

Tenga en cuenta que algunos protocolos tienen “caracteres” “EOF”. ASCII tiene “Fin del texto”, “Fin de la transmisión”, “Fin del bloque de transmisión” y “Fin del medio”. Otras respuestas han mencionado sistemas operativos antiguos. Yo mismo ingreso ^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 conductos pueden tener caracteres ^D y ^Z en cualquier lugar y solo indican EOF cuando se quedan sin bytes). Las cadenas C terminan con el '\0' carácter, pero eso también significa que no pueden Contiene el personaje '\0'. Es por eso que todas las funciones de datos que no son cadenas de C funcionan usando un char matriz (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 […]
fin de semana

que se expande a una expresión constante entera, con tipo int y un valor negativo, que es devuelto por varias funciones para indicar fin de archivoes decir, no más entradas de una secuencia;

  • El estándar C no garantiza que EOF no sea un personaje.

    –Eric Postpischil

    12 de septiembre de 2012 a las 14:59

  • Su edición no muestra que EOF no es igual a un valor de carácter. El hecho de que EOF indique el final del archivo no impide que iguale un valor de char. El hecho de que EOF sea negativo no impide que iguale un valor de char. (Permitir que EOF sea un valor de carácter es una molestia pero, como dice la respuesta a la que me vinculé, no impide que una implementación de C se ajuste al estándar de C).

    –Eric Postpischil

    12 de septiembre de 2012 a las 16:02

  • Eso no cambia el problema. gente haciendo ((charVar = getchar()) == EOF) verá un comportamiento incorrecto. Lo que estás diciendo es que pueden obtener un EOF falso y prematuro cuando leen eso. char valor que pasa a ser igual EOF cuando es promovido a inten lugar de repetirse para siempre porque no char alguna vez será igual EOF. La solución sigue siendo la misma: ((intVar = getchar()) == EOF)

    – aib

    13 de septiembre de 2012 a las 0:32


  • @Santropedro: Sí, las respuestas están mal. Varias rutinas de biblioteca estándar devuelven un carácter como un unsigned char convertido en un intpor lo que debe tener un valor no negativo, que no puede ser igual a EOF porque EOF es negativo Sin embargo, una de las definiciones de “carácter” en el estándar C es “representación de bits que cabe en un byte”. Y muchas personas manejan personajes usando el char tipo, que puede estar firmado. (De hecho, fgets toma una char *.) Entonces puede ser posible tener un char x cuyo valor es igual EOF pero que podría ser válidamente impreso con fputc y otras funciones.

    –Eric Postpischil

    20 de julio de 2019 a las 1:07

  • @Santropedro: Lo que esto significa, para responder correctamente la pregunta, es que uno debe detectar EOF utilizando el valor de retorno de funciones como fgetcque devuelve un carácter como un unsigned char convertido a int o EOF. Eso funcionará en todas las implementaciones de C hipotéticas exóticas discutidas en el enlace que proporcioné. (Para escribir código incluso para esas implementaciones, use el feof funcin.) Pero uno no debe asumir que un char el valor no es igual EOF.

    –Eric Postpischil

    20 de julio de 2019 a las 1:15

avatar de usuario
pmakholm

No. EOF no es un carácter, sino un estado del identificador de archivo.

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 fin de semana (^D) que en algunos casos casi señala lo mismo.

Cuando la biblioteca C estándar usa un entero con signo para devolver caracteres y usa -1 para el final del archivo, esta es solo la señal para indicar que ocurrió un error. No tengo el estándar C disponible, pero para citar SUSv3:

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

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 personaje (en absoluto).

avatar de usuario
Axel Rietschin

los EOF carácter reconocido por el intérprete de comandos en Windows (y MSDOS, y CP/M) es 0x1a (decimal 26, también conocido como control+Z también conocido como SUB)

Todavía se puede usar hoy, por ejemplo, para marcar el final de un encabezado legible por humanos en un archivo binario: si el archivo comienza con "Some description\x1a" el usuario puede volcar el contenido del archivo a la consola usando el TYPE comando y el volcado se detendrá en el EOF personajees decir, imprimir Alguna descripción y parar, en vez de seguir con la basura que sigue.

avatar de usuario
onoma

Esto depende del sistema, pero a menudo -1. Ver aquí

avatar de usuario
keith molinero

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 fue impreso en la consola. Espero que esto ayude.

  • Si eof es un carácter, ¿por qué está imprimiendo con %d?

    – Koray Tugay

    6 de junio de 2015 a las 18:22

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad