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)?
¿Representando EOF en código C?
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 tipoint
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 ‘losfgetc
la función obtiene [the next] personaje como ununsigned char
convertido en unint
‘. En cualquier sistema dondesizeof(char) != sizeof(int)
por lo tanto, EOF es distinto de cualquierchar
.–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
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 EOF
el 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 semanaque 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 igualEOF
cuando es promovido aint
en lugar de repetirse para siempre porque nochar
alguna vez será igualEOF
. 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 unint
por lo que debe tener un valor no negativo, que no puede ser igual aEOF
porqueEOF
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 elchar
tipo, que puede estar firmado. (De hecho,fgets
toma unachar *
.) Entonces puede ser posible tener unchar x
cuyo valor es igualEOF
pero que podría ser válidamente impreso confputc
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 comofgetc
que devuelve un carácter como ununsigned char
convertido aint
oEOF
. 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 elfeof
funcin.) Pero uno no debe asumir que unchar
el valor no es igualEOF
.–Eric Postpischil
20 de julio de 2019 a las 1:15
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).
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.
onoma
Esto depende del sistema, pero a menudo -1. Ver aquí
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
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