2010-06-20 18 views
14

Después de hacer búsquedas exhaustivas en Google y visitar muchos foros, aún no he encontrado una buena respuesta exhaustiva para esta pregunta. Muchos de los foros sugieren usar la función get line istream& getline (char* s, streamsize n). Mi pregunta es ¿qué ocurre si no sé cuál es la longitud de cada línea y no puedo predecir cuál será el tamaño? Además, ¿qué es equivalente en C?¿Cómo leer una línea de un archivo de texto en c/C++?

¿Hay alguna función específica en c/C++ para leer una sola línea cada vez desde un archivo de texto?

Explicación, con los fragmentos de código me ayudarán mucho.

+1

Esto no es un DUP ya que pide específicamente sobre C , y el supuesto 'dup' pregunta específicamente sobre C++. – sje397

+0

@sje Esta pregunta también dice C++ ... –

+1

@DannyBeckett Sí, me di cuenta. No creo que eso sea relevante para mi punto, ya que este (a diferencia del otro) pregunta acerca de C, lo que lo hace cualitativamente diferente. – sje397

Respuesta

18

En c, puede usar fopen y getch. Por lo general, si no puede estar exactamente seguro de la longitud de la línea más larga, puede asignar un gran búfer (por ejemplo, 8 kb) y casi se garantiza la obtención de todas las líneas.

Si existe la posibilidad de que tengas líneas muy largas y tengas que procesar línea por línea, puedes crear un búfer razonable y usar realloc para duplicar su tamaño cada vez que te acerques a llenarlo.

#include <stdio.h> 
#include <stdlib.h> 

void handle_line(char *line) { 
    printf("%s", line); 
} 

int main(int argc, char *argv[]) { 
    int size = 1024, pos; 
    int c; 
    char *buffer = (char *)malloc(size); 

    FILE *f = fopen("myfile.txt", "r"); 
    if(f) { 
     do { // read all lines in file 
     pos = 0; 
     do{ // read one line 
      c = fgetc(f); 
      if(c != EOF) buffer[pos++] = (char)c; 
      if(pos >= size - 1) { // increase buffer length - leave room for 0 
      size *=2; 
      buffer = (char*)realloc(buffer, size); 
      } 
     }while(c != EOF && c != '\n'); 
     buffer[pos] = 0; 
     // line is now in buffer 
     handle_line(buffer); 
     } while(c != EOF); 
     fclose(f);   
    } 
    free(buffer); 
    return 0; 
} 
+1

char c; ??? cerrar (f) ?? y malloc.h !!! no stdlib.h – Nyan

+0

@Nyan - porras, fijo – sje397

3

getline() es lo que estás buscando. Utiliza cadenas en C++, y no necesita saber el tamaño antes de tiempo.

Suponiendo espacio de nombres std:

ifstream file1("myfile.txt"); 
string stuff; 

while (getline(file1, stuff, '\n')) { 
     cout << stuff << endl; 
} 

file1.close(); 
+0

Nota: Desea 'std :: getline (std :: istream &, std :: string &)' not 'std :: istream :: getline'. –

+2

¿Cómo lo haríamos en C? –

22

En C++, puede utilizar la función global std :: getline, se toma una cadena y una corriente y un delimitador opcional y lee 1 línea hasta que se alcanza el delimitador especificado . Un ejemplo:

#include <string> 
#include <iostream> 
#include <fstream> 

int main() { 
    std::ifstream input("filename.txt"); 
    std::string line; 

    while(std::getline(input, line)) { 
     std::cout<<line<<'\n'; 
    } 

    return 0; 
} 

Este programa lee cada línea de un archivo y la envía a la consola.

Para C probablemente estés usando fgets, ha pasado un tiempo desde que usé C, lo que significa que estoy un poco oxidado, pero creo que puedes usar esto para emular la funcionalidad del programa C++ anterior como por lo que:

#include <stdio.h> 

int main() { 
    char line[1024]; 
    FILE *fp = fopen("filename.txt","r"); 

    //Checks if file is empty 
    if(fp == NULL) {      
     return 1; 
    } 

    while(fgets(line,1024,fp)) { 
     printf("%s\n",line); 
    } 

    return 0; 
} 

con la limitación de que la línea no puede ser más largo que la longitud máxima del buffer que usted está leyendo a.

+0

Gracias. ¿Cómo haríamos lo mismo en C? cualquier cosa? –

+0

Actualicé mi publicación con la forma en que recuerdo haberlo hecho, espero que sea correcta como lo describí, de lo contrario corregiré la publicación una vez que la gente señale lo que hice mal. – Jacob

+0

Gracias, me preguntaba si había una mejor manera de usar un búfer de longitud fija. Supongo que ahora sé que necesitamos codificar el tamaño del búfer. –

7

En C, fgets(), y necesita saber el tamaño máximo para evitar el truncamiento.

+0

Esta es la mejor respuesta para C, debería tener más votos ascendentes. (En realidad, 'getline' es mejor, pero no estándar.) –

4

im no es tan bueno en C, pero creo que este código debe conseguir que una sola línea completa hasta el final ...

#include<stdio.h> 

int main() 
{  
    char line[1024];  
    FILE *f=fopen("filename.txt","r");  
    fscanf(*f,"%[^\n]",line);  
    printf("%s",line);  
}  
+1

Debe evitar 'fscanf' porque causa desbordamientos de búfer. Proporciona ahora la manera de limitar el tamaño de la entrada al tamaño del búfer al que está escribiendo (aquí, 'línea'). –

Cuestiones relacionadas