Fin del archivo (EOF) en C


Actualmente estoy leyendo el libro C Programming Language de Ritchie & Kernighan. Y estoy bastante confundido sobre el uso de EOF en la función getchar().

Primero, quiero saber por qué el valor de EOF es -1 y por qué el valor de getchar()!=EOF es 0. Perdóneme por mi pregunta, pero realmente no entiendo. Realmente lo intenté, pero no puedo.

Luego traté de ejecutar el ejemplo en el libro que puede contar el número de caracteres utilizando el código a continuación, pero parece que nunca salgo de la loop incluso si presiono enter, así que me pregunto cuándo llegaría al EOF?

main(){
   long nc;
   nc = 0;
   while (getchar() != EOF)
       ++nc;
   printf("%ld\n", nc);
}

Entonces, leo el mismo problema en Problema con EOF en C. La mayoría de la gente aconseja que en lugar de usar EOF, use el terminador \n o el terminador nulo '\0', lo que tiene mucho sentido.

¿Significa esto que el ejemplo en el libro sirve para otro propósito?

 49
Author: Community, 2010-12-05

3 answers

EOF indica "fin del archivo". Una nueva línea (que es lo que sucede cuando se presiona enter) no es el final de un archivo , es el final de una línea , por lo que una nueva línea no termina este bucle.

El código no está mal[*], simplemente no hace lo que parece esperar. Se lee hasta el final de la entrada, pero parece que quieres leer solo hasta el final de una línea.

El valor de EOF es -1 porque tiene que ser diferente de cualquier valor devuelto de getchar que es un valor real caracter. Así que getchar devuelve cualquier valor de carácter como un carácter sin signo, convertido a int, que por lo tanto será no negativo.

Si está escribiendo en la terminal y desea provocar un fin de archivo, use CTRL-D (sistemas de estilo unix) o CTRL-Z (Windows). Luego, después de que se haya leído toda la entrada, getchar() devolverá EOF, y por lo tanto getchar() != EOF será false, y el bucle terminará.

[*] bien, tiene un comportamiento indefinido si la entrada es más que caracteres LONG_MAX debido a entero desbordamiento, pero probablemente podemos perdonarlo en un simple ejemplo.

 64
Author: Steve Jessop,
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-03-19 15:32:13

EOF es -1 porque así es como se define. El nombre es proporcionado por las cabeceras estándar de la biblioteca que usted #include. Lo hacen igual a -1 porque tiene que ser algo que no se puede confundir con un byte real leído por getchar(). getchar() informa los valores de los bytes reales usando un número positivo (0 hasta 255 inclusive), por lo que -1 funciona bien para esto.

El operador != significa "no igual". 0 significa falso, y cualquier otra cosa significa verdadero. Entonces, lo que sucede es que llamamos a la función getchar() , y compare el resultado con -1 (EOF). Si el resultado no fue igual a EOF, entonces el resultado es verdadero, porque las cosas que no son iguales no son iguales. Si el resultado fue igual a EOF, entonces el resultado es falso, porque las cosas que son iguales no son (no iguales).

La llamada a getchar() devuelve EOF cuando se llega al "final del archivo". En lo que respecta a C, la 'entrada estándar' (los datos que está dando a su programa al escribir en la ventana de comandos) es como un archivo. Por supuesto, siempre puedes escribe más, así que necesitas una forma explícita de decir "He terminado". En sistemas Windows, esto es control-Z. En sistemas Unix, esto es control-D.

El ejemplo en el libro no es "incorrecto". Depende lo que realmente quieres hacer. Leer hasta EOF significa que lees todo, hasta que el usuario dice "He terminado", y entonces no puedes leer más. Leer hasta '\n ' significa leer una línea de entrada. Leer hasta '\0 ' es una mala idea si espera que el usuario escriba la entrada, porque es difícil o imposible producir este byte con un teclado en el símbolo del sistema:)

 13
Author: Karl Knechtel,
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
2015-03-15 11:40:43

Eso son muchas preguntas.

  1. Por qué EOF es -1: normalmente -1 en las llamadas al sistema POSIX se devuelve por error, así que supongo que la idea es"EOF es un tipo de error"

  2. Cualquier operación booleana (incluyendo != ) devuelve 1 en caso de que sea TRUE, y 0 en caso de que sea FALSE, por lo que getchar() != EOF es 0 cuando es FALSE, lo que significa getchar() devuelto EOF.

  3. Para emular EOF al leer desde stdin presione Ctrl + D

 6
Author: Drakosha,
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
2010-12-05 12:24:22