2010-12-05 21 views
45

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().Fin del archivo (EOF) en C

Primero, quiero saber por qué el valor de EOF es -1 y por qué el valor de getchar()!=EOF es 0. Perdónenme 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 siguiente código, pero parece que nunca salgo del ciclo, incluso si presiono enter, entonces me pregunto cuándo alcanzaría el EOF?

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

Entonces, leí el mismo problema en Problem with EOF in C. La mayoría de las personas aconseja que, en lugar de utilizar EOF, utilice el terminador \ n o el terminador nulo '\ 0', que tiene mucho sentido.

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

+5

Usted entiende que el libro la mención es por los autores originales del lenguaje C, ¿verdad? –

Respuesta

61

EOF indica "fin de fichero". Una nueva línea (que es lo que sucede cuando 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 ciclo.

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

El valor de EOF es -1 porque debe ser diferente de cualquier valor de retorno de getchar que sea un carácter real. Por lo tanto, getchar devuelve cualquier valor de carácter como un carácter sin signo, convertido a int, que por lo tanto no será negativo.

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

[*] bueno, tiene un comportamiento indefinido si la entrada es más que caracteres LONG_MAX debido al desbordamiento de enteros, pero probablemente podamos perdonar eso en un ejemplo simple.

+0

ahora sé el problema ... es por eso que no puedo ver el resultado ... es porque estoy usando Dev-C++ y no tiene ningún sistema ("pausa"), así que tengo que escribir eso al final de la código. – newbie

+2

En realidad CTRL + D no provoca un EOF. Simplemente termina su terminal, que a su vez el kernel sabe que no se pueden leer más bytes por lo que no hay datos disponibles en el archivo de entrada estándar descriptior. –

+0

@newbie función 'system' crea un nuevo shell y ejecuta el comando que se le pasa. El comando es ejecutado por el shell del sistema y no está relacionado con el compilador. –

5

Eso es muchas preguntas.

  1. Por qué EOF es -1: -1 por lo general en el sistema POSIX llamadas se devuelve en caso de error, así que supongo que la idea es "EOF es una especie de error"

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

  3. con el fin de emular EOF cuando se lee de stdin pulse Ctrl + D

+0

Las operaciones booleanas devuelven ** distinto de cero ** para verdadero y cero para falso. Hay una diferencia –

+7

No, los operadores están definidos para devolver 1. Cualquier valor distinto de cero es "verdadero" en un contexto booleano (por ejemplo, una condición 'if()' o 'while()'). –

+0

Eso es 6.5.9/3. –

13

EOF es -1 porque así es como se define. El nombre lo proporcionan los encabezados de biblioteca estándar que #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 utilizando el 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 verdad. Entonces, lo que sucede es que llamamos a la función getchar() y comparamos 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, el resultado es falso, porque las cosas que son iguales no son (no iguales).

La llamada a getchar() devuelve EOF cuando llega al "final del archivo". En lo que respecta a C, la 'entrada estándar' (los datos que le está dando a su programa al escribir en la ventana de comandos) es como un archivo. Por supuesto, siempre puede escribir más, por lo que necesita 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 de lo que realmente desea hacer. Leer hasta EOF significa que lees todo, hasta que el usuario dice "He terminado", y luego ya no puedes leer más. Leer hasta '\ n' significa que lee 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 :)

+0

Control-2 o control-space lo produce bastante fácilmente ... –