2010-05-21 13 views
6

Necesito leer un archivo y enviar el texto a una cadena para que pueda analizarlo. Sin embargo, el programa no sabrá exactamente cuánto dura el archivo, entonces, ¿qué haría si quisiera usar fgets(), o hay una mejor alternativa?¿Cómo usar los fgets si no sabes la cantidad de caracteres que se deben leer?

Nota:

char *fgets(char *str, size_t num, FILE *stream); 
+1

Su título sugiere que desea utilizar los datos pero el texto implica que está buscando alternativas. ¿Qué fue lo que te hizo buscar Fgets en primer lugar ...? – Default

Respuesta

8

No olvide que fgets() lee una línea a la vez, sujeto a tener suficiente espacio.

Los seres humanos rara vez escriben líneas de más de ... 80, 256, elegir un número ... caracteres. POSIX sugiere una longitud de línea de 4096. Por lo tanto, yo suelo usar:

char buffer[4096]; 

while (fgets(buffer, sizeof(buffer), fp)) 
{ 
    ...process line... 
} 

Si usted está preocupado de que alguien podría proporcionar más de 4K de datos en una sola línea (y un archivo por máquina, tales como HTML o JSON , podría contener eso), entonces debes decidir qué hacer a continuación. Usted puede hacer cualquiera de los siguientes (y es probable que algunas otras opciones que no he mencionado):

  1. Procese las líneas demasiado largas en bits sin suponer que haya una nueva línea entre ellas.
  2. Asigne memoria para una línea más larga (digamos 8K para comenzar), copie los 4K iniciales en el búfer asignado y lea más datos en la segunda mitad del búfer, iterando hasta encontrar el final de la línea.
  3. Utilice la función POSIX 2008 getline() que está disponible en Linux. Hace la asignación de memoria para ti.
0

asignar un búfer (el que str puntos a), y pasan el tamaño de la memoria intermedia para num. El espacio real utilizado solo será la longitud del texto leído por fgets.

Algo así como:

char str[1000]; 
fgets(str, 1000, &file); 

Si la línea siguiente sólo se dispone de 10 caracteres antes del salto de línea, a continuación, str sostendrá esos 10 caracteres, el salto de línea, y el terminador nulo.

Editar: en caso de que haya alguna confusión, no pretendo que lo anterior parezca como si el espacio adicional en el búfer no estuviera en uso. Solo quise ilustrar que no es necesario saber con anticipación cuánto tiempo va a durar la cuerda, siempre que pueda ponerle una longitud máxima.

+0

¿Cómo es eso? A menos que reasigne el búfer, aún se está utilizando espacio adicional. –

+0

Me refiero al espacio en el búfer, no al espacio en la memoria. Además, la pregunta del OP no era sobre cómo ahorrar memoria. – danben

3

Puede usar los datos de forma iterativa, pero una alternativa más sencilla es (stdio.h's) getline. Está en POSIX, pero no es estándar.

Sin embargo, como está usando C++, ¿puede usar las funciones de std :: string como getline de iostream?

Cuestiones relacionadas