usar sintaxis que funciona fputs fputc como comando c char eof unsigned fgetc

sintaxis - que es fgetc en c



* ¿Podría*un carácter sin signo ser igual a EOF? (4)

Esta pregunta ya tiene una respuesta aquí:

Al usar fgetc para leer el siguiente carácter de una secuencia, generalmente verifica que el final del archivo no fue alcanzado por

if ((c = fgetc (stream)) != EOF)

donde c es de tipo int . Entonces, o se ha alcanzado el final del archivo y la condición fallará, o c será un carácter unsigned convertido a int , que se espera que sea diferente de EOF ya que EOF está garantizado como negativo. Bien ... aparentemente.

Pero hay un pequeño problema ... Por lo general, el tipo de caracteres no tiene más de 8 bits, mientras que int debe tener al menos 16 bits, por lo que cada unsigned char será representable como un int . Sin embargo, en el caso de que char tenga 16 o 32 bits (lo sé, este nunca es el caso en la práctica ...), no hay ninguna razón por la que no se pueda tener sizeof(int) == 1 , por lo que sería (teóricamente!) posible que fgetc (stream) devuelva EOF (u otro valor negativo) pero ese final de archivo no se ha logrado ...

¿Estoy equivocado? ¿Hay algo en el estándar C que impida que fgetc devuelva EOF si no se ha alcanzado el fin del archivo? (Si es así, ¡no podría encontrarlo!). ¿O la sintaxis if ((c = fgetc (stream)) != EOF) no es totalmente portátil? ...

EDITAR: De hecho, este fue un duplicado de la Pregunta # 3860943. No encontré esa pregunta en la primera búsqueda. ¡Gracias por tu ayuda! :-)


Creo que debes confiar en el error de transmisión.

ch = fgetc(stream); if (ferror(stream) && (ch == EOF)) /* end of file */;

Del estándar

Si se produce un error de lectura, se establece el indicador de error para la secuencia y la función fgetc devuelve EOF.

Editar para una mejor versión

ch = fgetc(stream); if (ch == EOF) { if (ferror(stream)) /* error reading */; else if (feof(stream)) /* end of file */; else /* read valid character with value equal to EOF */; }


Estoy de acuerdo con tu lectura.

C Standard dice (C11, 7.21.7.1 La función fgetc p3):

Si se establece el indicador de fin de archivo para la secuencia, o si la secuencia se encuentra al final del archivo, se establece el indicador de fin de archivo para la secuencia y la función fgetc devuelve EOF. De lo contrario, la función fgetc devuelve el siguiente carácter de la secuencia de entrada a la que apunta la transmisión. Si se produce un error de lectura, se establece el indicador de error para la secuencia y la función fgetc devuelve EOF.

No hay nada en el Estándar (suponiendo UCHAR_MAX > INT_MAX ) que fgetc en una implementación alojada para devolver un valor igual a EOF que no sea un indicador de fin de archivo ni un indicador de condición de error.


Si está leyendo una transmisión que es solo ASCII estándar, no hay riesgo de recibir el carácter equivalente a EOF antes del final real del archivo, porque los códigos de caracteres válidos ASCII solo llegan a 127. Pero podría suceder al leer un archivo binario. El byte necesitaría ser 255 (sin signo) para corresponderse con un signo -1 firmado, y nada impide que aparezca en un archivo binario.

Pero sobre su pregunta específica (si hay algo en el estándar), no exactamente ... pero observe que fgetc promueve el personaje como un carácter sin signo, por lo que de todos modos no será negativo en este caso. El único riesgo sería si hubiera arrojado explícita o implícitamente el valor de retorno a char firmado (por ejemplo, si su variable c fue firmada como char).

NOTA: como se menciona @Ulfalizer en los comentarios, hay un caso raro en el que puede necesitar preocuparse: si sizeof (int) == 1, y está leyendo un archivo que contiene caracteres que no son ascii, entonces puede obtener un -1 valor de retorno que no es el EOF real. Tenga en cuenta que los entornos en los que esto sucede son bastante raros (que yo sepa, compiladores para microcontroladores de gama baja de 8 bits, como el 8051). En tal caso, la opción segura sería probar feof () como se sugirió @pmg.


Tu preguntaste:

¿Hay algo en el estándar C que impida que fgetc devuelva EOF si no se ha alcanzado el fin del archivo?

Por el contrario, la norma permite explícitamente la devolución de EOF cuando ocurre un error.

Si se produce un error de lectura, se establece el indicador de error para la secuencia y la función fgetc devuelve EOF .

En las notas al pie, veo:

Se puede distinguir un fin de archivo y un error de lectura mediante el uso de las funciones feof y ferror .

También preguntaste:

¿O la sintaxis if ((c = fgetc (stream)) != EOF) no es totalmente portátil?

En la plataforma teórica donde CHAR_BIT es más de 8 y sizeof(int) == 1 , esa no será una forma válida de verificar que se haya alcanzado el final de archivo. Para eso, tendrás que recurrir a feof y ferror .

c = fgetc (stream); if ( !feof(stream) && !ferror(stream) ) { // Got valid input in c. }