Riga per riga la lettura in C e C++?

Voglio leggere riga per riga da un file in C o C++, e io so come fare, che quando mi danno per scontata una certa dimensione fissa di una linea, ma c’è un modo semplice per in qualche modo si calcola o ottenere la dimensione esatta necessaria per una linea o tutte le righe nel file? (Lettura parola per parola, fino a quando newline è anche un bene per me se qualcuno può farlo in quel modo.)

Utilizzare getline
C e C++ sono linguaggi completamente diversi, producendo completamente diverse soluzioni.
Mi piace l’odore di casa, a lavoro la mattina
Il problema di fondo è che una riga di testo è una variabile record di lunghezza. È terminata da un carattere di nuova riga. Dal momento che la dimensione è fornito prima il testo viene avviato, non è possibile inserire attraverso la lettura di un numero fisso di caratteri. Si deve leggere carattere per carattere fino a quando il carattere di terminazione è trovato. Diventa così la base per i sovraccarichi del buffer (non sapendo quanta memoria preallocare).

OriginaleL’autore mushroom | 2011-04-08

7 Replies
  1. 7

    Se si utilizza in streaming lettore, tutto questo sarà nascosto. Vedere getline. L’esempio che segue è basato sul codice qui.

    //getline with strings
    #include <iostream>
    #include <fstream>
    #include <string>
    using namespace std;
    
    int main () {
      string str;
      ifstream ifs("data.txt");
      getline (ifs,str);
      cout << "first line of the file is " << str << ".\n";
    }
    Ottenere informazioni da un file OP sta chiedendo.
    cin può benissimo essere sostituito da un flusso di file; cin potrebbe essere reindirizzato da un file comunque.

    OriginaleL’autore Jeff Foster

  2. 4

    In C, se si dispone di POSIX 2008 librerie (le versioni più recenti di Linux, per esempio), è possibile utilizzare il POSIX getline() funzione. Se non hai la funzione nelle librerie, è possibile implementare abbastanza facilmente, che è probabilmente meglio di inventare la propria interfaccia per fare il lavoro.

    In C++, è possibile utilizzare std::getline().

    Anche se le due funzioni hanno lo stesso nome di base, le convenzioni di chiamata e la semantica sono molto diverse (perché i linguaggi C e C++ sono molto diverse) – tranne che si sia mai letto una riga di dati da un flusso di file, naturalmente.

    Non c’è un modo semplice per dire quanto è grande la linea più lunga in un file con l’esclusione di leggere tutto il file per capire, che tipo di spreco.

    OriginaleL’autore Jonathan Leffler

  3. 3

    Vorrei utilizzare un IFStream e utilizzare getline per leggere da un file.

    http://www.cplusplus.com/doc/tutorial/files/

    int main () {
        string line;
        ifstream myfile ("example.txt");
        if (myfile.is_open())
        {
            while ( myfile.good() )
            {
                getline (myfile,line);
                cout << line << endl;
            }
            myfile.close();
        }
        else cout << "Unable to open file"; 
    
        return 0;
    }
    Problema è che il file di stato non può essere impostato male il tentativo di getline, in modo da controllare prima di fare affidamento sulla linea della variabile contenuto. Per esempio, il flusso di EOF flag non è impostato fino a quando viene tentata una lettura alla fine del file. Mi raccomando while (getline(stream, line)) { ... } quindi è possibile controllare la ragione per la terminazione al di fuori del ciclo se si cura….
    OP, indicato C O C++. La mia risposta era in C++, così risponde alla domanda. @Tony, sono d’accordo con voi su questo.

    OriginaleL’autore Stealth Rabbi

  4. 1

    Non è possibile ottenere la lunghezza di linea fino a dopo la lettura. Si può, comunque, di leggere in un buffer più volte fino a raggiungere la fine della riga.

    Per la programmazione in c, provare a utilizzare fgets per leggere una riga di codice. Legge n caratteri o interrompere se si incontra un carattere di nuova riga. Si può leggere in un piccolo buffer di dimensione n, fino all’ultimo carattere di una stringa è un ritorno a capo.

    Vedere il link qui sopra per ulteriori informazioni.

    Qui è un esempio su come leggere un display, una linea completa di file utilizzando un piccolo buffer:

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
       FILE * pFile;
    
       const int n = 5;
       char mystring [n];
       int lineLength = 0;
    
       pFile = fopen ("myfile.txt" , "r");
       if (pFile == NULL) 
       {
           perror ("Error opening file");
       }
       else 
       {
    
            do 
            {
                fgets (mystring , n , pFile);
                puts (mystring);    
                        lineLength += strlen(mystring); 
            } while(mystring[strlen ( mystring)-1] != '\n' && !feof(pFile));
    
           fclose (pFile);
       }
    
       printf("Line Length: %d\n", lineLength);
       return 0;
    }
    Non è questo il “io so come fare, che quando mi danno per scontata una certa dimensione fissa di una linea” parte della domanda?
    No, non è possibile fare di più con questo che con una piccola modifica. Se si conosce l’esatta dimensione della linea di impostare la lunghezza della stringa di esattamente che + 1. Se si conosce la dimensione massima della linea di impostare la lunghezza della stringa di max + 1. Ma se non si sa scrivere un anello intorno alla lettura e verificare se l’ultimo carattere della lettura è un carattere di fine riga.
    Ho modificato il codice per meglio illustrare l’utilizzo di questa istanza.
    Se non si controlla feof(pFile), si rischia di imbattersi in un ciclo infinito.
    Sì, ho visto il tuo codice ed è stata appena messa in. Buona pesca.

    OriginaleL’autore Steve

  5. 0

    In C++, è possibile utilizzare il std::getline funzione, che prende un flusso di legge e fino alla prima '\n' carattere. In C, vorrei solo utilizzare fgets e mantenere la riassegnazione di un buffer fino a quando l’ultimo carattere è il '\n', quindi siamo sicuri di avere letto tutta la linea.

    C++:

    std::ifstream file("myfile.txt");
    std::string line;
    std::getline(file, line);
    std::cout << line;

    C:

    //I didn't test this code I just made it off the top of my head.
    FILE* file = fopen("myfile.txt", "r");
    size_t cap = 256;
    size_t len = 0;
    char* line = malloc(cap);
    
    for (;;) {
        fgets(&line[len], cap - len, file);
        len = strlen(line);
        if (line[len-1] != '\n' && !feof(file)) {
            cap <<= 1;
            line = realloc(line, cap);
        } else {
            break;
        }
    }
    
    printf("%s", line);

    OriginaleL’autore Marlon

  6. 0

    getline è solo POSIX, qui è una ANSI (NON max-linea-dimensione info necessarie!):

    const char* getline(FILE *f,char **r)
    {
      char t[100];
      if( feof(f) )
        return 0;
      **r=0;
      while( fgets(t,100,f) )
      {
        char *p=strchr(t,'\n');
        if( p )
        {
          *p=0;
          if( (p=strchr(t,'\r')) ) *p=0;
          *r=realloc(*r,strlen(*r)+1+strlen(t));
          strcat(*r,t);
          return *r;
        }
        else
        {
          if( (p=strchr(t,'\r')) ) *p=0;
          *r=realloc(*r,strlen(*r)+1+strlen(t));
          strcat(*r,t);
        }
      }
      return feof(f)?(**r?*r:0):*r;
    }

    e ora e ‘ facile e breve principali:

      char *line,*buffer = malloc(100);
      FILE *f=fopen("yourfile.txt","rb");
      if( !f ) return;
      setvbuf(f,0,_IOLBF,4096);
      while( (line=getline(f,&buffer)) )
        puts(line);
      fclose(f);
      free(buffer);

    funziona su windows per Windows E Unix-textfiles,
    funziona su Unix per Unix E Windows-textfiles

    OriginaleL’autore user411313

  7. 0

    Qui è un C++ modo di leggere le linee, utilizzando std algoritmi e iteratori:

    #include <iostream>
    #include <iterator>
    #include <vector>
    #include <algorithm>
    
    struct getline :
      public std::iterator<std::input_iterator_tag, std::string>
    {
        std::istream* in;
        std::string line;
        getline(std::istream& in) : in(&in) {
            ++*this;
        }
        getline() : in(0) {
        }
        getline& operator++() {
            if(in && !std::getline(*in, line)) in = 0;
        }
        std::string operator*() const {
            return line;
        }
        bool operator!=(const getline& rhs) const {
            return !in != !rhs.in;
        }
    };
    
    int main() {
        std::vector<std::string> v;
        std::copy(getline(std::cin), getline(), std::back_inserter(v));
    }

    OriginaleL’autore Robᵩ

Lascia un commento