Saltar al contenido

¿Qué es EOF y cómo activarlo?

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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *