2012-06-15 18 views
9

En el libro sistema Linux Programación He leído algunos como este:fgetc, comprobando EOF

fgetc devuelve el carácter leído como un elenco unsigned char a un int o EOF el final del archivo o error. Un error común es el uso de fgetc:

char c; 
if ((c = fgetc()) != EOF) {...} 

la versión correcta de este código es:

int c; 
if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... } 

Así que, por qué no puedo emitir un valor de retorno a char antes de comparar con EOF? ¿Por qué tengo que comparar EOF exactamente con int? Como EOF se definió como -1, ¿normalmente no se convierte en char?
¿Hay plataformas/compiladores donde no es cierto?

+0

posible duplicado de ["while (! Feof (archivo))" siempre es incorrecto] (http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – jww

+0

@jww: esta pregunta no usa 'feof()' por lo que no es un duplicado de "[' while (! feof (archivo)) 'siempre está equivocado] (http://stackoverflow.com/questions/5431941/while-feof- file-is-always-wrong) ". –

Respuesta

10

No se puede convertir el valor de retorno a char porque el valor de retorno podría ser EOF, y EOF depende del sistema y no es igual a ningún código de carácter válido. link

Normalmente es -1 pero no debe suponer que.

Comprobar esta gran respuesta de la c-faq-site:

Dos modos de fallo son posibles si, como en el fragmento anterior, el valor de retorno de getchar se asigna a un char.

  1. Si se firma tipo char, y si EOF se define (como es usual) como -1, el carácter con el valor decimal 255 ('\ 377' o '\ xff' en C) será con signo extendido y se comparará igual a EOF, terminando prematuramente la entrada. (suponiendo 8 bits de char).

  2. Si el tipo char es sin signo, un valor EOF real se truncará (por tener sus bits de orden superior descartados, probablemente resultante en 255 o 0xff) y no será reconocido como EOF, resultando en eficacia infinito entrada.

espero que ayude!

Editado: (añadió el comentario @FatalError en esta respuesta, esto se explica en el sitio C-faq pero esto parece más claro para mí)

"Si lo lanzas a char a continuación, toma el EOF el mismo valor que un carácter válido y, por lo tanto, no puede distinguirse de ese carácter. Eso solo debería ser una justificación suficiente para no hacer que el resultado sea un comentario de "@FatalError".

+0

¿y qué? No entiendo. después de lanzar el char será igual a '-1', ¿o no? – pproger

+0

mi char NO ESTÁ sin firmar, le di una muestra del código. – pproger

+0

@pproger La norma en realidad no ordena si 'char' solo está firmado o no. Si desea un char firmado y garantizado, debe usar 'signed char'. – Corbin

3

Hay dos posibilidades cuando se asigna el valor a un char antes de comparar con EOF:

  • char es un valor con signo. En ese caso, hay un personaje legítimo (a menudo ÿ, PEQUEÑA LETRA LATINA Y CON DIAGNÓSTICO, U + 00FF) que se malinterpretará como EOF.
  • char es un valor sin signo. En ese caso, EOF se traducirá a 0xFF, y luego se promocionará a int como un valor positivo, que nunca se comparará con EOF, que es un valor negativo.

De cualquier manera, el programa se va a portar mal algunas veces.

Existe (o, más exactamente, solía ser) la posibilidad de un error en el compilador de modo que la asignación ocurriera correctamente pero el valor asignado no se usara para la comparación. Eso llevaría al código que parece funcionar bien incluso cuando no lo es. Afortunadamente, es poco probable que sea un problema encontrado en un compilador moderno.