Mit fstream eine Liste in ein string array einlesen



  • Grundlagen von C++ oder von fstream ?

    Die Grundlagen von C++ behaupte ich mal zu können. Natürlich gibt es noch viel zu lernen von Dingen, die ich noch nicht kenne. Trotzdem will ich mit fstream mal etwas arbeiten 🙂



  • hanhau schrieb:

    Grundlagen von C++ oder von fstream ?

    Die Grundlagen von C++ behaupte ich mal zu können. Natürlich gibt es noch viel zu lernen von Dingen, die ich noch nicht kenne. Trotzdem will ich mit fstream mal etwas arbeiten 🙂

    Na dann musst du ein paar Zeilen deiner Datei posten und das Format erklären und erklären wie du die Daten genau in deinem Programm handhaben abspeichern willst.



  • Inwiefern bist Du mit einer Liste überfordert? Erstelle eine Liste und füge die Zeilen hinzu. Wo ist Dein Problem? Weißt Du nicht, was eine Liste ist? Oder weißt Du nicht, wo Du eine Referenz zu der Liste findest? Oder verstehst Du die Referenz nicht? Du musst schon sagen, an welcher Stelle es hängt. Aber erwarte nicht, dass eine Liste hier besser erklärt werden kann, als in einem fast beliebigen Lehrbuch.



  • Die Liste im .txt Format ....

    ------------------
    001 playerspawn "/test/lala/xxxxxx.png"
    002 grass "/test/lala/xxxxxx.png"
    003 dirt "/test/lala/xxxxxx.png"
    004 iron "/test/lala/xxxxxx.png"
    ...
    ..
    .
    ------------------

    Ich möchte nun pro Zeile einen Int-Wert einlesen, den Namen und den Pfad einer Textur. Diese Werte speichere ich in Array von "block"...

    class block{
    public:
    int ID;
    string name;
    string pfad;
    };

    Später möchte ich wieder auf die Daten zugreifen.



  • Ist das eventuell ein Lösungsansatz ?

    int zeile=1;
    int ID;
    string Name,Pfad;

    while(!datei.eof)
    {
    while(datei >> ID >> Name >> Pfad)
    {
    block[zeile].ID = ID;
    block[zeile].Name = Name;
    block[zeile].Pfad = Pfad;
    }
    zeile++;
    }

    Würde das so theoretisch funktionieren ?



  • Das hier ist der Standardweg.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <sstream>
    #include <vector>
    using namespace std;
    
    struct block
    {
    	int id;
    	string name;
    	string pfad;
    };
    
    istream& operator>>( istream& in, block& b )
    {
    	in >> b.id;
    	in >> b.name;
    	in >> b.pfad;
    	return in;
    }
    
    int main()
    {
    	istringstream datei( "001 playerspawn \"/test/lala/xxxxxx.png\"" );	
    	vector<block> blocks;
    	for(block b; datei>>b; blocks.push_back(b));
    }
    

    datei musst halt durch dein ifstream erstezen.



  • hanhau schrieb:

    Ist das eventuell ein Lösungsansatz ?

    int zeile=1;
    int ID;
    string Name,Pfad;

    while(!datei.eof)
    {
    while(datei >> ID >> Name >> Pfad)
    {
    block[zeile].ID = ID;
    block[zeile].Name = Name;
    block[zeile].Pfad = Pfad;
    }
    zeile++;
    }

    Würde das so theoretisch funktionieren ?

    Ne, du darfst nichts abspeichern was nicht auf Korrektheit geprüft wurde.



  • Danke für die Antwort !

    Werde das einmal ausprobieren 🙂
    PS.: Würde dann sonst eigentlich nur Schmarrn rauskommen, oder ?



  • Ach da unten hast noch eine while. Ja doch das sieht doch ok aus. Mach die while mit eof weg und es klappt. Und vielleicht solltest du bei 0 anfangen zu zählen.



  • Na dann ^^

    Ich probiere beide Lösungswege mal aus und schau, was besser für mich funktioniert 🙂 Danke nochmals dafür. Mit 0 könnte ich zum Zählen beginnen, muss es dann später dann halt auch einen Block 0 geben (Luft ? :D).



  • Also erstmal kann man diesen "Block" auch in ein struct packen, da dass ja nur eine Sammlung von Daten ist, die zusammen gehören. Außerdem bitte Klassen/Structs etc. groß schreiben.
    Dann würde ich den input operator hierfür überladen, dass kann z.B. so aussehen:

    istream& operator>>(istream& is, Block& b)
    {
        is >> b.ID >> b.name >> b.pfad;
        return is;
    }
    

    Damit könnte man dann ein paar Blocks einlesen, z.B.

    array<Block, 2> blocks;
    ifstream ist("blocks.txt");
    if (!ist) {
        cout << "Datei konnte nicht geoeffnet werden.\n";
        return 1;
    }
    for (auto& i : blocks)
        ist >> i;
    

    Kleines Beispielprogramm (benötigt C++11):

    #include <array>
    #include <iostream>
    #include <fstream>
    #include <string>
    
    using namespace std;
    
    struct Block {
        int ID;
        string name;
        string pfad;
    };
    
    istream& operator>>(istream& is, Block& b)
    {
        is >> b.ID >> b.name >> b.pfad;
        return is;
    }
    
    ostream& operator<<(ostream& os, const Block& b)
    {
        os << "ID: " << b.ID << '\n'
           << "Name: " << b.name << '\n'
           << "Pfad: " << b.pfad << '\n';
        return os;
    }
    
    int main()
    {
        array<Block, 2> blocks;
        ifstream ist("blocks.txt");
        if (!ist) {
            cout << "Datei konnte nicht geoeffnet werden.\n";
            return 1;
        }
        for (auto& i : blocks)
            ist >> i;
        for (const auto& i : blocks)
            cout << i << '\n';
    }
    

    Sollte die Anzahl einzulesender Blöcke nicht bekannt sein, tuts auch ein vector:

    vector<Block> blocks;
    Block b;
    while (ist >> b)
        blocks.push_back(b);
    // Oder etwas unverständlicher:
    #include <iterator>
    ...
    vector<Block> blocks {istream_iterator<Block>(ist), {}};
    

    Man beachte, dass ein Programm so ziemlichen Müll produzieren könnte. Es ist also eigentlich wichtig, dass du vor dem verwenden der Daten überprüfst, ob du auch was damit anfangen kannst. Wenn man die jetzt nur ausgibt, so wie im Beispiel, dann wirds eher nicht knallen, aber in einem nicht-trivialen Programm muss das unbedingt drin sein! Also error-handling ist eher dürftig in dem Programm, abgesehen von dem kleinen Test, ob die Datei überhaupt geöffnet werden konnte.



  • Danke auch für diesen Beitrag und Tipps 🙂

    Ja, überprüfen sollte ich im Programm dann schon die Liste/einzelnen Werte. Schließlich sollen die Liste später auch andere vervollständigen und ergänzen können 🙂


Anmelden zum Antworten