whole Lesen Sie die gesamte ASCII-Datei in C++ std:: string




std c++ ifstream (8)

Ich glaube nicht, dass Sie dies ohne eine explizite oder implizite Schleife tun können, ohne zuerst in ein char-Array (oder einen anderen Container) zu lesen und dann die Zeichenfolge zu konstruieren. Wenn Sie die anderen Fähigkeiten eines Strings nicht benötigen, können Sie dies mit vector<char> genauso machen, wie Sie gerade ein char * .

Diese Frage hat hier bereits eine Antwort:

Ich muss eine ganze Datei in den Speicher lesen und sie in eine C ++ std::string .

Wenn ich es in ein char[] lesen würde, wäre die Antwort sehr einfach:

std::ifstream t;
int length;
t.open("file.txt");      // open input file
t.seekg(0, std::ios::end);    // go to the end
length = t.tellg();           // report location (this is the length)
t.seekg(0, std::ios::beg);    // go back to the beginning
buffer = new char[length];    // allocate memory for a buffer of appropriate dimension
t.read(buffer, length);       // read the whole file into the buffer
t.close();                    // close file handle

// ... Do stuff with buffer here ...

Nun, ich möchte genau dasselbe machen, aber einen std::string anstelle von char[] . Ich möchte Schleifen vermeiden, dh ich will nicht :

std::ifstream t;
t.open("file.txt");
std::string buffer;
std::string line;
while(t){
std::getline(t, line);
// ... Append line to buffer and go on
}
t.close()

Irgendwelche Ideen?


Es gibt ein paar Möglichkeiten. Ich benutze gerne einen Stringstream als Vermittler:

std::ifstream t("file.txt");
std::stringstream buffer;
buffer << t.rdbuf();

Jetzt ist der Inhalt von "file.txt" in einer Zeichenkette als buffer.str() verfügbar.

Eine andere Möglichkeit (obwohl ich es sicherlich nicht mag) ist viel mehr wie dein Original:

std::ifstream t("file.txt");
t.seekg(0, std::ios::end);
size_t size = t.tellg();
std::string buffer(size, ' ');
t.seekg(0);
t.read(&buffer[0], size); 

Offiziell ist dies nicht erforderlich, um unter dem C ++ 98 oder 03 Standard zu arbeiten (String ist nicht erforderlich, um Daten zusammenhängend zu speichern), aber tatsächlich funktioniert es mit allen bekannten Implementierungen, und C ++ 11 und später erfordern einen zusammenhängenden Speicher Es ist garantiert, mit ihnen zu arbeiten.

Warum ich das letztere auch nicht mag: erstens, weil es länger und schwerer zu lesen ist. Zweitens, weil es erfordert, dass Sie den Inhalt der Zeichenfolge mit Daten initialisieren, die Sie nicht interessieren, dann schreiben Sie sofort über diese Daten (ja, die Zeit zu initialisieren ist in der Regel trivial im Vergleich zum Lesen, also ist es wahrscheinlich egal , aber für mich fühlt es sich irgendwie falsch an). Drittens, in einer Textdatei bedeutet Position X in der Datei nicht unbedingt, dass Sie X-Zeichen gelesen haben, um diesen Punkt zu erreichen - es ist nicht erforderlich, Dinge wie Zeilenende-Übersetzungen zu berücksichtigen. Auf realen Systemen, die solche Übersetzungen ausführen (zB Windows), ist das übersetzte Formular kürzer als das, was in der Datei enthalten ist (dh "\ r \ n" in der Datei wird "\ n" in der übersetzten Zeichenkette), also alles, was Sie getan haben ist etwas mehr Platz reserviert, den Sie nie benutzen. Auch das verursacht nicht wirklich ein großes Problem, fühlt sich aber trotzdem ein bisschen falsch an.


Update: Es stellt sich heraus, dass diese Methode, während sie STL-Idiomen gut folgt, tatsächlich überraschend ineffizient ist! Tun Sie dies nicht mit großen Dateien. (Siehe: http://insanecoding.blogspot.com/2011/11/how-to-read-in-file-in-c.html )

Sie können einen streambuf-Iterator aus der Datei machen und die Zeichenfolge damit initialisieren:

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str((std::istreambuf_iterator<char>(t)),
                 std::istreambuf_iterator<char>());

Nicht sicher, woher du die t.open("file.txt", "r") . Soweit ich weiß, ist das keine Methode, die std::ifstream hat. Es sieht so aus, als hättest du es mit fopen verwechselt.

Bearbeiten: Beachten Sie auch die zusätzlichen Klammern um das erste Argument des Zeichenfolgenkonstruktors. Diese sind wesentlich . Sie verhindern das Problem, das als " am meisten ärgerlicher Parse " bekannt ist, das in diesem Fall nicht wirklich einen Kompilierfehler wie gewöhnlich verursacht, sondern Ihnen interessante (gelesene: falsche) Ergebnisse liefert.

Nach dem Punkt von KeithB in den Kommentaren folgt hier eine Möglichkeit, den gesamten Speicher im Voraus zu reservieren (anstatt sich auf die automatische Neuzuweisung der String-Klasse zu verlassen):

#include <string>
#include <fstream>
#include <streambuf>

std::ifstream t("file.txt");
std::string str;

t.seekg(0, std::ios::end);   
str.reserve(t.tellg());
t.seekg(0, std::ios::beg);

str.assign((std::istreambuf_iterator<char>(t)),
            std::istreambuf_iterator<char>());

Versuchen Sie eine dieser beiden Methoden:

string get_file_string(){
    std::ifstream ifs("path_to_file");
    return string((std::istreambuf_iterator<char>(ifs)),
                  (std::istreambuf_iterator<char>()));
}

string get_file_string2(){
    ifstream inFile;
    inFile.open("path_to_file");//open the input file

    stringstream strStream;
    strStream << inFile.rdbuf();//read the file
    return strStream.str();//str holds the content of the file
}

Du findest das vielleicht nicht in irgendeinem Buch oder auf irgendeiner Seite, aber ich habe herausgefunden, dass es ziemlich gut funktioniert:

ifstream ifs ("filename.txt");
string s;
getline (ifs, s, (char) ifs.eof());

Ich habe einen anderen Weg gefunden, der mit den meisten istream funktioniert, einschließlich std :: cin!

std::string readFile()
{
stringstream str;
ifstream stream("Hello_World.txt");
if(stream.is_open())
{
    while(stream.peek() != EOF)
    {
        str << (char) stream.get();
    }
    stream.close();
    return str.str();
}
}

Ich könnte es so machen:

void readfile(const std::string &filepath,std::string &buffer){
    std::ifstream fin(filepath.c_str());
    getline(fin, buffer, char(-1));
    fin.close();
}

Wenn das etwas verpönt ist, lassen Sie mich bitte wissen, warum


Ich denke, der beste Weg ist, String-Stream zu verwenden. einfach und schnell !!!

ifstream inFile;
inFile.open(inFileName);//open the input file

stringstream strStream;
strStream << inFile.rdbuf();//read the file
string str = strStream.str();//str holds the content of the file

cout << str << endl;//you can do anything with the string!!!






standard-library