Dateiinhalte richtig formatieren und auslesen
-
Hallo liebe Comm,
ich möchte gerne, wie es im Titel schon steht, eine Datei haben, die ich gezielt auslesen kann. Angenommen die Datei sieht folgendermaßen aus:
Item 1: Holzschild Kosten 300 Gold 10 Verteidigung Item 2: Eisenschild Kosten 700 Gold 15 VerteidigungStellt euch vor, es würden noch viele mehr Items gleich aufgebaut folgen.
Wie mache ich nun, dass das Programm alles ausliest und dabei die Items büdelt und so weiß, was zu was gehört. Außerdem muss er irgendwie kontrollieren, ob auch alles korrekt angegeben ist, sodass, wenn z.b. die Datei beschädigt ist und der Inhalt nicht richtig ist, sagen wir, bei Item 2 fehlt das "Gold" Feld, er das auch merkt.
Da muss ich doch die Datei irgendwie formatieren, oder?Ich bitte um eure Ratschläge und vielleicht hat sowas ja schonmal jemand gemacht.
Danke im Voraus.
-
ich würde mir eine grammatik bauen die sowas alles vorsieht, dazu kann man sich dann einen parser konfigurieren (z.B. boost::spirit, google ruhig mal) und den lässt man das auch noch verarbeiten
soviel zur theorie, praktisch wird es da aber sicher das ein oder andere problem geben
-
Wäre eine Möglichkeit, kommt drauf an wie komplex die Datei ist.
Du könntest die Datei einfach zeilenweise einlesen. Dann die einzelnen Zeilen überprüfen ob es ein neues Item ist, ansonsten einfach dem letzten Item zuordnen (und überprüfen ob die Zeile korrekt ist oder was fehlt).
-
Hallo Kralo9,
mache Dir für jedes Attribut eine kleine
struct, und füge einen Streaming-Operator hinzu, so daß Du eine Instanz dieserstructLesen und ggf. auch schreiben kannst. Dort kannst Du dann auch abfragen, ob die erwarteten Schlüsselwörter in der Datei stehen.
Daneben ist es sinnvoll eine kleine Helferstruktur (hierchecks.u) zu bauen, die bestimmte Worte überprüft. Alles zusammen etwa so:#include <iostream> #include <fstream> #include <string> #include <algorithm> // std::find #include <vector> struct Schild { enum Art { Holz=0, Eisen, Titan }; Art art; }; std::istream& operator>>( std::istream& in, Schild& schild ) { static std::string const arten[] = {"Holzschild", "Eisenschild", "Titanschild"}; std::string s; int idx; if( in >> s && (idx = std::find( arten, arten+sizeof(arten)/sizeof(*arten), s ) - arten) >= sizeof(arten)/sizeof(*arten) ) in.setstate( std::ios_base::failbit ); // Lesefehler, eingelesener Schildtyp ist unbekannt else if( in ) // alles ok schild.art = Schild::Art( idx ); return in; } struct check { check( const std::string& key ) : key_( key ) {} std::string key_; }; std::istream& operator>>( std::istream& in, check c ) { std::string w; if( in >> w && w != c.key_ ) in.setstate( std::ios_base::failbit ); // das erwartet Wort 'wort' folgte nicht return in; } struct Preis { int wertInGold_; }; std::istream& operator>>( std::istream& in, Preis& preis ) { return in >> preis.wertInGold_ >> check("Gold"); } class Item { public: friend std::istream& operator>>( std::istream& in, Item& item ); private: int nr_; Schild schild_; Preis preis_; int staerke_; }; // -- ein Item einlesen std::istream& operator>>( std::istream& in, Item& item ) { in >> check("Item") >> item.nr_ >> check(":"); in >> item.schild_; in >> check("Kosten") >> item.preis_; in >> item.staerke_ >> check("Verteidigung"); return in; } int main() { using namespace std; vector< Item> items; ifstream datei("input.txt"); if( !datei.is_open() ) { cerr << "Fehler beim Oeffnen der Datei" << endl; return -2; } for( Item i; datei >> i; ) items.push_back( i ); cout << items.size() << " Eintraege gelesen" << endl; return 0; }Gruß
Werner