¿Es posible distinguir el error devuelto por fgets?

3 minutos de lectura

¿Es posible distinguir el error devuelto por fgets
Miket25

Al observar el estándar ISO C11 para fgets §7.21.7.2, 3, el valor de retorno se indica con respecto al código de sinopsis:

#include <stdio.h>
char *fgets(char* restrict s, int n, FILE* restrict stream);

los fgets función devuelve s si tiene éxito. Si se encuentra el final del archivo y no se han leído caracteres en la matriz, el contenido de la matriz permanece sin cambios y se devuelve un puntero nulo. Si se produce un error de lectura durante la operación, el contenido de la matriz es indeterminado y se devuelve un puntero nulo.

El estándar dice que se devuelve un puntero nulo para un final de archivo y no se han leído caracteres o se produce un error de lectura. Mi pregunta es, solo de fgetsy el puntero nulo devuelto, ¿hay alguna manera de distinguir cuál de los dos casos causó el error?

  • Sospecharía que hay una razón para ferror().

    – demasiado honesto para este sitio

    23 de julio de 2017 a las 4:42

  • Las funciones feof() y ferror() están diseñados para eso. Sé consciente de while (!feof(file)) siempre esta mal

    –Jonathan Leffler

    23 de julio de 2017 a las 4:45

  • Cuidado, antes de responder… “SOLO de fgets, y el puntero nulo devuelto”

    – Pushan Gupta

    23 de julio de 2017 a las 4:50

  • De todos modos, si establece en 0 el búfer de entrada, también puede ver lo que se ha leído parcialmente.

    – Frankie_C

    23 de julio de 2017 a las 10:09

  • @Frankie_C– “Si ocurre un error de lectura durante la operación, el contenido de la matriz es indeterminado”.

    – ad absurdum

    23 de julio de 2017 a las 10:18

1647678187 202 ¿Es posible distinguir el error devuelto por fgets
chux – Reincorporar a Monica

¿Hay alguna manera de distinguir cuál de los dos casos causó el error?

si, uso feof() y ferror() distinguir. @Nada nada


Sin embargo, es importante usarlo correctamente. Considere los dos códigos:

char buf[100];
fgets(s, sizeof s, stream);
if (feof(stream)) return "End-of-file occurred";
if (ferror(stream)) return "Input error occurred"; 


if (fgets(s, sizeof s, stream) == NULL) {
  if (feof(stream)) return "End-of-file occurred";
  if (ferror(stream)) return "Input error occurred"; 
  return "Should never get here";
}

El segundo prueba adecuadamente el valor de retorno contra NULLcomo sugiere OP.

El primero puede encontrar un problema raro. los ferror(stream) prueba una bandera. Esta bandera puede haber sido establecida por un previo Llamada de función de E/S activada stream así que esto fgets() no es necesariamente la causa del error. Lo mejor es comprobar el resultado de fgets() para ver si esta la función falló.

Si el código es para seguir usando stream después de detectar un error, asegúrese de borrar el error antes de continuar, por ejemplo, para volver a intentarlo.

if (ferror(stream)) {   
  clearerr(stream);
  return "Input error occurred");
}

Tenga en cuenta que clearerr() borra los indicadores de error y de fin de archivo.

Lo mismo se aplica para feof()sin embargo, la mayoría del código está escrito para dejar de usar stream una vez que un fin de archivo es verdadero.


hay un 3er patológico forma de recibir NULL y tampoco feof() ni ferror() devoluciones NULL como se detalla en ¿fgets() devuelve NULL con un búfer corto compatible? La lectura cuidadosa de la especificación C tiene 3 “si”, de los cuales es posible que ninguno de ellos sea cierto, ya que falta la especificación, lo que implica UB.

¿Es posible distinguir el error devuelto por fgets
Nada nada

Si la falla ha sido causada por una condición de fin de archivo, adicionalmente activa el indicador eof (ver feof()). El contenido de la matriz a la que apunta str no se modifica en este caso. Si la falla ha sido causada por algún otro error, activa el indicador de error (ver ferror()). El contenido de la matriz a la que apunta str es indeterminado (es posible que ni siquiera termine en nulo).

Por lo tanto, debe verificar si feof() y ferror() para determinar el error.

Desde este sitio

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad