txt manejo lenguaje leer guardar fputs fputc ejercicios ejemplos datos archivos archivo c io stdio fgets fgetc

manejo - C fgets versus fgetc para leer la línea



manejo de archivos en c ejemplos (5)

Necesito leer una línea de texto (terminada por una nueva línea) sin hacer suposiciones sobre la duración. Entonces ahora me enfrento a las posibilidades:

  • Usa fgets y comprueba cada vez si el último carácter es una línea nueva y añádelo continuamente a un buffer
  • Lee cada personaje usando fgetc y ocasionalmente realloc el buffer

La intuición me dice que la variante de fgetc podría ser más lenta, pero de nuevo no veo cómo pueden hacerlo los fgetc sin examinar a cada personaje (también mi intuición no siempre es tan buena). Las líneas son bastante grandes, por lo que el rendimiento es importante.

Me gustaría saber los pros y los contras de cada enfoque. Gracias de antemano.


¿Su entorno proporciona la función getline(3) ? Si es así, yo diría que síganlo.

La gran ventaja que veo es que asigna el búfer en sí (si lo desea), y realloc() el búfer que pasa si es demasiado pequeño. (Entonces, esto significa que debe pasar algo obtenido de malloc() ).

Esto elimina parte del dolor de fgets / fgetc, y puedes esperar que quien escribió la biblioteca C que lo implementa se encargó de hacerlo eficiente.

Bonificación: la página man de Linux tiene un buen ejemplo de cómo usarla de manera eficiente.


Asignaría un gran buffer y luego usaría fgets, checking, reallocing y repeting si no ha leído hasta el final de la línea.

Cada vez que lee (ya sea a través de fgetc o fgets) está haciendo una llamada al sistema que lleva tiempo, quiere minimizar el número de veces que sucede, por lo que las llamadas se vuelven menos frecuentes y la iteración en la memoria es más rápida.

Si está leyendo desde un archivo, mmap() ing en el archivo es otra opción.


Si el rendimiento es importante para usted, generalmente desea llamar a getc lugar de a fgetc . El estándar intenta facilitar la implementación de getc como una macro para evitar la sobrecarga de llamada a la función.

Después de eso, lo más importante es probablemente tu estrategia para asignar el buffer. La mayoría de las personas usa incrementos fijos (por ejemplo, cuando / si nos quedamos sin espacio, asignamos otros 128 bytes). Aconsejaría utilizar un factor constante, por lo que si se queda sin espacio, asigne un buffer que sea, digamos, 1 1/2 veces el tamaño anterior.

Especialmente cuando getc se implementa como una macro, la diferencia entre getc y fgets suele ser bastante mínima, por lo que es mejor que se concentre en otros problemas.


Si puede establecer una longitud de línea máxima, incluso una grande, entonces uno de ellos haría el truco. De lo contrario, varias llamadas fgets seguirán siendo más rápidas que múltiples llamadas fgetc porque la sobrecarga de esta última será mayor.

Una mejor respuesta, sin embargo, es que no vale la pena preocuparse por la diferencia de rendimiento hasta que tenga que hacerlo y a menos que sea necesario. Si fgetc es lo suficientemente rápido, ¿qué importa?


Sugiero usar fgets() junto con la asignación dinámica de memoria, o puede investigar la interfaz para getline() que está en el estándar POSIX 2008 y está disponible en máquinas Linux más recientes. Eso hace las cosas de asignación de memoria para ti. Debe mantener las pestañas en la longitud del búfer, así como su dirección, por lo que incluso puede crear una estructura para manejar la información.

Aunque fgetc() también funciona, es marginalmente más extraño, pero solo marginalmente. Debajo de las cubiertas, utiliza los mismos mecanismos que fgets() . Las strchr() internas pueden explotar una operación más rápida, análoga a strchr() , que no está disponible cuando llamas a fgetc() directamente.