whole - std c++ ifstream




Lesen Sie die gesamte ASCII-Datei in C++ std:: string (6)

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?


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());

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.


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 * .


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();
}
}

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
}

Wenn Sie glibmm , können Sie Glib::file_get_contents .

#include <iostream>
#include <glibmm.h>

int main() {
    auto filename = "my-file.txt";
    try {
        std::string contents = Glib::file_get_contents(filename);
        std::cout << "File data:\n" << contents << std::endl;
    catch (const Glib::FileError& e) {
        std::cout << "Oops, an error occurred:\n" << e.what() << std::endl;
    }

    return 0;
}




standard-library