Eine Funktion wie fscanf in der STL bzw. ifstream
-
Hi,
ich will eine Datei laden und einlesen. Die Datei sieht ungefähr so aus:
Num 5 [Ball Count: Mass, Radius, ....]Ich kann die erste Zeile lesen. Jetzt suche ich aber Funktion wie fscanf, wo ich nach dem Keyword [Ball %d: %d, %d, ...] suchen und auslesen kann. Aber ich weiß nicht wie ich das anstellen soll und getline gibt mir die ganze Zeile.
Kann mir einer verraten wie die Funktion lautet bei ifstream, da ich nicht gerne fopen benutzen möchte.
Vielen Dank schonmal!
-
Parser bauen oder Regular Expressions bemühen.Für beides gibts was bei boost.
-
Ich will ja einen Parser schreiben, aber ich suche ja eine Funktion von ifstream oder string, wo ich halt testen kann.
-
Ich würde bei fscanf bleiben. Ist doch gerade für solche Fälle ziemlich praktisch und bietet eine angenehme Syntax. Und man spart sich den eigenen Parser-Bau, weil man bloß keine C-Funktionen nutzen will...
-
std::ifstream reader(...); //... std::string id; char delimiter; int count //... reader >> id >> count >> delimiter >> mass >> radius;
-
STLNoob schrieb:
Kann mir einer verraten wie die Funktion lautet bei ifstream, da ich nicht gerne fopen benutzen möchte.
Selber basteln ist vielleicht auch eine Option:
ifstream in("meinInputFile.txt"); int num; in >> Word("Num") >> num; { Bracket<'[',']'> check( in ); int count, mass, radius, foo; in >> Word("Ball") >> count >> Char<':'> >> mass >> Char<','> >> radius >> Char<','> >> foo; } if( in ) // alles korrekt gelesenDas sind dann die von Dir benötigten Funktionen:
struct Word { explicit Word( const std::string& ref ) : m_ref( ref ) {} friend std::istream& operator>>( std::istream& in, const Word& w ) { std::string ref; if( in >> ref && ref != w.m_ref ) in.setstate( std::ios_base::failbit ); return in; } std::string m_ref; }; template< char C > std::istream& Char( std::istream& in ) { char c; if( in >> c && c != C ) in.setstate( std::ios_base::failbit ); return in; } template< char Open, char Close > struct Bracket // : boost::noncopyable { explicit Bracket( std::istream& in ) : m_in( in >> Char< Open > ) {} ~Bracket() { m_in >> Char< Close >; } private: std::istream& m_in; };
-
Ich würde bei fscanf bleiben. Ist doch gerade für solche Fälle ziemlich praktisch und bietet eine angenehme Syntax. Und man spart sich den eigenen Parser-Bau, weil man bloß keine C-Funktionen nutzen will...
Die Syntax find ich eher gruselig. Warum ich davon abraten würde ist aber die Fehleranfälligkeit. Wenn die Typen im Formatstring nicht mit dem Inhalt der Datei übereinstimmen kanns knallen. Das gilt übrigens auch wenn man unbedarft direkt aus nem ifstream in z.B nen int streamt. Deshalb lieber richte Parser bauen, die können dann auch fehlerhafte Eingaben ab. Oder aber wenn ausreicht eben RegEx.
-
Tyrdal schrieb:
Wenn die Typen im Formatstring nicht mit dem Inhalt der Datei übereinstimmen kanns knallen.
Ja, dann hat man einen Fehler beim Programmieren gemacht, den man schleunigst beheben sollte (insofern ist ein 'Knallen' u.U. gar nicht so schlecht).
-
Oder beim Schreiben der Konfigdatei? Oder aber ein böser Schelm nutzt sowas aus? Das ist schlicht und einfach nicht robust.