Si encuentras algún detalle que no comprendes puedes dejarlo en la sección de comentarios y te responderemos lo más rápido posible.
Solución:
Tl; dr
Por lo general, puede “activar EOF” en un programa que se ejecuta en un terminal con un CONTROL+D pulsación de tecla justo después de la última entrada flush.
¿Qué significa EOF? ¿Cómo puedo activarlo?
EOF significa Fin de archivo.
“Activar EOF” en este caso significa aproximadamente “hacer que el programa sepa que no se enviarán más entradas”.
En este caso, desde getchar()
devolverá un número negativo si no se lee ningún carácter, la ejecución finaliza.
Pero esto no solo se aplica a su programa específico, se aplica a muchas herramientas diferentes.
En general, la “activación de EOF” se puede hacer con un CONTROL+D pulsación de tecla justo después de la última entrada flush (es decir, enviando una entrada vacía).
Por ejemplo con cat
:
% cat >file # Hit ENTER
foo # Hit ENTER and CTRL+D
%
¿Qué sucede debajo del capó al golpear? CONTROL+D es que la entrada tecleada desde la última entrada flush se vacía; cuando esto pasa a ser una entrada vacía el read()
syscall llamado en los retornos STDIN del programa 0
, getchar()
devuelve un número negativo (-1
en la biblioteca GNU C) y esto a su vez se interpreta como EOF1.
1 – https://stackoverflow.com/a/1516177/4316166
TL; DR: EOF no es un personaje, es un macro se utiliza para evaluar el retorno negativo de una función de lectura de entrada. Uno puede usar control+D mandar EOT
carácter que forzará el retorno de la función -1
Todo programador debe RTFM
Consultemos el “Manual de referencia de CA”, de Harbison y Steele, 4ª ed. desde 1995, página 317:
El entero negativo EOF es un valor que no es una codificación de un “carácter real”. . . Por ejemplo, fget (sección 15.6) devuelve EOF cuando está al final del archivo, porque no hay un “carácter real” para leer.
Esencialmente EOF
no es un personaje, sino más bien un valor entero implementado en stdio.h
representar -1
. Por lo tanto, la respuesta de kos es correcta en lo que respecta a eso, pero no se trata de recibir una entrada “vacía”. La nota importante es que aquí EOF sirve como valor de retorno (de getchar()
) comparación, para no significar un personaje real. los man getchar
apoya que:
VALOR DEVUELTO
fgetc (), getc () y getchar () devuelven el carácter leído como una conversión de caracteres sin firmar a un int o EOF al final del archivo o error.
gets () y fgets () devuelven s en caso de éxito, y NULL en caso de error o cuando se produce el final del archivo mientras no se han leído caracteres.
ungetc () devuelve c en caso de éxito o EOF en caso de error.
Considera el while
bucle: su propósito principal es repetir la acción si la condición entre paréntesis es true. Mirar de nuevo:
while ((c = getchar ()) != EOF)
Básicamente dice que sigas haciendo cosas si c = getchar()
devuelve código exitoso (0
o superior; por cierto, es algo común, intente ejecutar un comando exitoso, luego echo $?
y luego falló echo $?
y ver los números que devuelven). Entonces, si obtenemos con éxito el carácter y le asignamos a C, el código de estado devuelto es 0, el error es -1. EOF
Se define como -1
. Por lo tanto, cuando la condición -1 == -1
ocurre, los bucles se detienen. ¿Y cuando sucederá eso? Cuando no hay más carácter para conseguir, cuando c = getchar()
falla. Podrías escribir while ((c = getchar ()) != -1)
y todavía funcionaría
Además, volvamos al código real, aquí hay un extracto de stdio.h
/* End of file character.
Some things throughout the library rely on this being -1. */
#ifndef EOF
# define EOF (-1)
#endif
Códigos ASCII y EOT
Aunque el carácter EOF no es un personaje real, sin embargo, existe un EOT
Carácter (Fin de transmisión), que tiene un valor decimal ASCII de 04; está vinculado a control+D atajo (representado también como meta carácter ^D
). El carácter de fin de transmisión utilizado para significar el cierre de un flujo de datos cuando se usaban computadoras para controlar las conexiones telefónicas, de ahí la denominación de “fin de transmisión”.
Entonces es posible enviar ese valor ascii al programa de esa manera, tenga en cuenta el $' 4'
cual es el EOT:
[email protected]:$ ./a.out <<< "a,b,c $' 4'"
digits = 1 0 0 0 1 0 0 0 0 0, white space = 2, other = 9
Por lo tanto, podemos decir que existe, pero no es imprimible.
Nota al margen
A menudo olvidamos que en el pasado las computadoras no eran tan versátiles: los diseñadores tienen que hacer uso de todos los teclados key disponible. Por lo tanto, enviando EOT
carácter con CtrlD sigue "enviando un carácter", no a diferencia de escribir A mayúscula, ShiftA, todavía le da a la computadora una entrada con disponible keys. Por lo tanto, EOT es un personaje real en el sentido de que proviene del usuario, es legible por computadora (aunque no imprimible, no visible para humanos), existe en la memoria de la computadora
Comentario de Byte Commander
Si intenta leer desde / dev /null, eso también debería devolver un EOF, ¿verdad? ¿O qué consigo allí?
Sí, exactamente correcto, porque en /dev/null
no hay un carácter real para leer, por lo tanto, c = getchar()
volverá -1
código, y el programa se cerrará de inmediato. De nuevo El comando no devuelve EOF. EOF es solo una variable constante igual a -1, que usamos para comparar el código de retorno de la función getchar. EOF
no existe como personaje, es solo un static valor en el interior stdio.h
.
Manifestación:
# cat /dev/null shows there's no readable chars
DIR:/xieerqi
[email protected]:$ cat /dev/null | cat -A
# Bellow is simple program that will open /dev/null for reading. Note the use of literal -1
DIR:/xieerqi
[email protected]:$ cat readNull.c
#include
void main()
char c;
FILE *file;
file = fopen("/dev/null", "r");
if (file)
printf ("Before while loopn");
while ((c = getc(file)) != -1)
putchar(c);
printf("After while loopn");
fclose(file);
DIR:/xieerqi
[email protected]:$ gcc readNull.c -o readNull
DIR:/xieerqi
[email protected]:$ ./readNull
Before while loop
After while loop
Otro clavo en el ataúd
A veces se intenta demostrar que EOF es un personaje con un código como este:
#include
int main(void)
printf("%c", EOF);
return 0;
El problema con eso es que el tipo de datos char puede ser un valor firmado o sin firmar. Además, son el tipo de datos direccionable más pequeño, lo que los hace muy muy útiles en microcontroladores, donde la memoria es limitada. Entonces en lugar de declarar int foo = 25;
es común ver en microcontroladores con poca memoria char foo = 25;
o algo similar. Además, los caracteres pueden estar firmados o sin firmar.
Se podría verificar que el tamaño en bytes con un programa como este:
#include
int main(void)
printf("Size of int: %lun",sizeof(int));
printf("Sieze of char: %lun",sizeof(char));
//printf("%s", EOF);
return 0;
[email protected]:$ ./EOF
Size of int: 4
Sieze of char: 1
Cuál es exactamente el punto ? El punto es que EOF se define como -1, pero el tipo de datos char puede imprimir valores enteros.
ESTÁ BIEN . . .y que si intentamos imprimir char como string ?
#include
int main(void)
printf("%s", EOF);
return 0;
Obviamente un error, pero no obstante, el error nos dirá algo interesante:
[email protected]: $ gcc EOF.c -o EOF
EOF.c: En la función 'main': EOF.c: 4: 5: advertencia: el formato '% s' espera un argumento de tipo 'char *', pero el argumento 2 tiene tipo 'int'
[-Wformat=]printf ("% s", EOF);
Valores hexadecimales
Imprimir EOF como un valor hexadecimal da FFFFFFFF
, un valor de 16 bits (8 bytes), complemento de dos de un -1
.
#include
int main(void)
printf("This is EOF: %Xn", EOF);
printf("This is Z: %Xn",'Z');
return 0;
Producción:
DIR:/xieerqi
[email protected]:$ ./EOF
This is EOF: FFFFFFFF
This is Z: 5A
Otra cosa curiosa ocurre con el siguiente código:
#include
int main(void)
char c;
if (c = getchar())
printf ("%x",c);
return 0;
Si uno presiona Cambio + A , obtenemos el valor hexadecimal 41, obviamente igual que en la tabla ASCII. Pero para control + D , tenemos ffffffff
, de nuevo - el valor de retorno de getchar()
guardado en c
.
DIR:/xieerqi
[email protected]:$ gcc EOF.c -o ASDF.asdf
DIR:/xieerqi
[email protected]:$ ./ASDF.asdf
A
41
DIR:/xieerqi
[email protected]:$ ./ASDF.asdf
ffffffff
Consulte otros idiomas
Observe que otros lenguajes evitan esta confusión, porque operan evaluando el estado de salida de una función, no comparándolo con un macro. ¿Cómo se lee un archivo en Java?
File inputFile = new File (filename);
Scanner readFile = new Scanner(inputFile);
while (readFile.hasNext())
//more code bellow
¿Qué tal Python?
with open("/etc/passwd") as file:
for line in file:
print line
EOF representa fin del documento. Si bien no sé cómo activar el siguiente símbolo, puede ejecutar el siguiente programa mediante la canalización de un archivo, que envía el EOF señal al final:
echo "Some sample text" | ./a.out
dónde a.out
es tu fuente compilada
Sección de Reseñas y Valoraciones
Si para ti ha resultado de ayuda este artículo, sería de mucha ayuda si lo compartes con el resto desarrolladores de esta forma contrubuyes a difundir nuestra información.