Wie lese ich Zeile für Zeile oder eine ganze Textdatei gleichzeitig?


84

Ich bin in einem Tutorial, das Dateien vorstellt (wie man von \ zu Datei liest und schreibt)

Erstens ist dies keine Hausaufgabe, sondern nur allgemeine Hilfe, die ich suche.

Ich weiß, wie man ein Wort nach dem anderen liest, aber ich weiß nicht, wie man eine Zeile nach dem anderen liest oder wie man die gesamte Textdatei liest.

Was ist, wenn meine Datei 1000 Wörter enthält? Es ist nicht praktisch, jedes Wort zu lesen.

Meine Textdatei mit dem Namen (Lesen) enthält Folgendes:

Ich liebe es Spiele zu spielen Ich liebe es zu lesen Ich habe 2 Bücher

Folgendes habe ich bisher erreicht:

#include <iostream>
#include <fstream>

using namespace std;
int main (){

  ifstream inFile;
  inFile.open("Read.txt");

  inFile >>

Gibt es eine Möglichkeit, die gesamte Datei auf einmal zu lesen, anstatt jede Zeile oder jedes Wort einzeln zu lesen?


4
Hier gibt es genau definierte Antworten: stackoverflow.com/questions/551082/c-read-lines-from-file
sampson-chen


Wort für Wort zu lesen ist nur unwesentlich langsamer als Zeile für Zeile. Wenn Sie tatsächlich Wörter benötigen, ist es besser, Wörter zu lesen. Lesen Sie Zeilen, wenn Sie mit zeilenorientierten Daten wie CSV-Dateien arbeiten.

@Arkadiy das ist falsch. Bei einer 100-MiB-Datei dauert das zeilenweise Lesen leicht Sekunden, während das Lesen eines Blocks mit 4 KiB Sekunden weniger als eine Sekunde dauert.
Vallentin

@Vallentin: Da alle Streams gepuffert sind, erfolgt das eigentliche Lesen der Festplatte bereits blockweise. Der Rest manipuliert nur Daten im Speicher.

Antworten:


158

Sie können verwenden std::getline:

#include <fstream>
#include <string>

int main() 
{ 
    std::ifstream file("Read.txt");
    std::string str; 
    while (std::getline(file, str))
    {
        // Process str
    }
}

Beachten Sie auch, dass es besser ist, den Dateistream mit den Dateinamen im Konstruktor zu erstellen, als ihn explizit zu öffnen (dasselbe gilt für das Schließen, lassen Sie den Destruktor einfach die Arbeit erledigen).

Weitere Dokumentationen zu std::string::getline()finden Sie unter CPP Reference .

Der wahrscheinlich einfachste Weg, eine ganze Textdatei zu lesen, besteht darin, diese abgerufenen Zeilen zu verketten.

std::ifstream file("Read.txt");
std::string str;
std::string file_contents;
while (std::getline(file, str))
{
  file_contents += str;
  file_contents.push_back('\n');
}  

9
Obwohl nicht offensichtlich, ist dies while(getline(f, line)) { ...}wirklich der empfohlene Weg, dies zu tun. Dies wird hier erklärt: gehrcke.de/2011/06/… --- dort finden Sie auch nützliche Ansätze für eine ordnungsgemäße Fehlerbehandlung.
Dr. Jan-Philip Gehrcke

1
Der obige Code wird nicht kompiliert ohne#include <iostream>
Tyguy7

@ Tyguy7 Warum wäre #include <iostream>erforderlich? Es scheint mir das <fstream>und <string>sind genug. Wenn Sie meinen std::getline, ist es in <string>, nicht in <iostream>.
Fabio sagt Reinstate Monica

@FabioTurati Ich bin mir nicht sicher, ich weiß nur, dass alles gut kompiliert wurde, sobald ich es aufgenommen habe.
Tyguy7

19

Ich weiß, dass dies ein wirklich sehr alter Thread ist, aber ich möchte auch auf einen anderen Weg hinweisen, der eigentlich sehr einfach ist ... Dies ist ein Beispielcode:

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {

    ifstream file("filename.txt");
    string content;

    while(file >> content) {
        cout << content << ' ';
    }
    return 0;
}

2
Schöne Antwort, ich habe dies mit einem Stringstream anstelle von Cout verwendet, um die gesamte Datei in einen riesigen Stringstream zu bringen
bjackfly

5

Ich denke, Sie könnten die Funktion istream .read () verwenden. Sie können einfach eine Schleife mit einer angemessenen Blockgröße erstellen und direkt in den Speicherpuffer lesen und dann an einen beliebigen Speichercontainer (z. B. std :: vector) anhängen. Ich könnte ein Beispiel schreiben, aber ich bezweifle, dass Sie eine vollständige Lösung wollen. Bitte lassen Sie mich wissen, wenn Sie zusätzliche Informationen benötigen.


Ich weiß nicht, wer diese Antwort abgelehnt hat, aber das ist gut, vielleicht bin ich nicht von Ihren Standards, aber ich benutze das gleiche
Javasist

4

Dazu kann man auch die in C ++ bereitgestellte Freopen-Funktion verwenden - http://www.cplusplus.com/reference/cstdio/freopen/ und die Datei Zeile für Zeile wie folgt lesen:

#include<cstdio>
#include<iostream>

using namespace std;

int main(){
   freopen("path to file", "rb", stdin);
   string line;
   while(getline(cin, line))
       cout << line << endl;
   return 0;
}

1

Eine andere Methode, die noch nicht erwähnt wurde, ist std::vector.

std::vector<std::string> line;

while(file >> mystr)
{
   line.push_back(mystr);
}

Dann können Sie einfach über den Vektor iterieren und ändern / extrahieren, was Sie benötigen /


4
Das vectorist ein unnötiger Schritt. Sie könnten über die ifstreamVerwendung iterieren std::istream_iterator<std::string>(inFile).
Joseph Mansfield
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.