Parsing



  • Hallo miteinander!

    Ich habe ne Frage. Ich muss ein File parsen und die Information in einem Vektor speichern. Ich habe mittlerweile folgendes gemacht.
    Allerdings frage ich mich, was in die vorgegebene Methode "parse(void)" kommt.. :S
    Hat jemand eine Idee?

    Liebe Grüsse,
    Max

    parser::parser(std::string file_name_)
    {
    
    	std::ifstream file(file_name_.c_str());
    
    	if(!file.is_open())
    	{
    		std::cerr << "Konnte Datei nicht oeffnen." << file_name_ << std::endl;
    		return;
    	}
    
    	_ausgabe.clear();
    
    	while(file.good()) 
    	{
    		std::string surname;
    		std::string name;
    		std::string number;
    
    		file >> surname;
    		file >> name;
    		file >> number;
    
    		if(file.good())
    	{
    		_ausgabe.push_back(person(surname, name, number));
    	}
    
    		file.close();
    	}
    
    }
    
    void
    parser::parse(void)
    {
    
        // Code hier.
    
    }
    


  • Wahrscheinlich soll der Konstruktor nur den Member file_name_ initialisieren. Das eigentliche Parsen soll in parse stattfinden.



  • Sorry die etwas verspätete Antwort. Aber wie meinst du das genau?
    Ich kann ja nicht einfach das schreiben:

    parser::parser(std::string file_name_)
    {
        // TODO
    	std::ifstream file(file_name_.c_str());
    }
    

    ..weil ich "file" ja dann im void-Block verwende..



  • vermutlich soll der filename am Parserobjekt gespeichert werden und das öffnen und schließen der Datei auch mit ins parse()



  • file.close() ist unnötig, FSTREAMS KÖNNEN RAII



  • Damit ihr seht, was ich meine, habe ich hier mein Code:

    #include <iostream>
    
    #include <fstream>
    #include "parser.hpp"
    #include "person.hpp"
    #include <vector>
    #include <iterator>
    
    std::vector<person> _ausgabe; 
    
    parser::parser(std::string file_name_)
    {
        	std::ifstream file(file_name_.c_str());
    }
    
    void 
    	parser::parse(void)
    {
    
        // TODO
    
    	if(!file.is_open()) //hier wird mir ein Fehler angezeigt wegen "file", der nicht deklariert ist..
    	{
    		std::cerr << "Konnte Datei nicht oeffnen." << file_name_ << std::endl; //ebenfalls wieder wegen "file"...
    		return;
    	}
    
    	_ausgabe.clear();
    
    	while(file.good()) //"file"...
    {
    	std::string surname;
    	std::string name;
    	std::string number;
    
    	file >> surname;
    	file >> name;
    	file >> number;
    
    	if(file.good())
    	{
    		_ausgabe.push_back(person(surname, name, number));
    	}
    
    file.close();
    
    }
    }
    
    void
    parser::print(void)
    {
        	int total = 0;
    	std::vector<int>::iterator the_iterator = _ausgabe.begin();
    
    	while(the_iterator != _ausgabe.end() )
    	{
    		total += *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    
    void
    parser::print_reverse(void)
    {
    	std::vector<int> the_vector;
    	for(int i = the_vector.size(); i >= 0; i--)
    	{
    		the_vector.push_back(i);
    	}
    }
    

    Ich habe per Kommentar angebenen, was und wo es noch nicht richtig funktioniert. Weil ich nun die Zeile zur Initialisierung in eine andere Methode verschoben habe, weiss die untere nicht mehr, was "file" ist. Wie kann man das (und die anderen Fehler, die ich noch gar nicht gesehen habe) verbessern?
    Ich bin euch sehr dankbar.
    Liebe Grüsse, max.



  • 314159265358979 schrieb:

    file.close() ist unnötig, FSTREAMS KÖNNEN RAII

    Es bringt das Programm aber auch nicht zum Absturz oder hat sonstige negative Effekte. Wo ist dein Problem?



  • das file kannst du als member deiner parser klasse deklarieren (vermutlich in parser.hpp)

    class parser
    {
      private:
      std::ifstream file;
    };
    

    und ersetze ..

    parser::parser(std::string file_name_)
    {
     file.open(file_name_.c_str());
    }
    


  • theliquidwave schrieb:

    314159265358979 schrieb:

    file.close() ist unnötig, FSTREAMS KÖNNEN RAII

    Es bringt das Programm aber auch nicht zum Absturz oder hat sonstige negative Effekte. Wo ist dein Problem?

    Ich will dass RAII endlich benutzt wird, aber jeden zweiten Tag kommt einer daher, der es nicht tut. Ich frage mich: Woher kommt dieses falsche Wissen?



  • pepe75 schrieb:

    das file kannst du als member deiner parser klasse deklarieren (vermutlich in parser.hpp)

    class parser
    {
      private:
      std::ifstream file;
    };
    

    und ersetze ..

    parser::parser(std::string file_name_)
    {
     file.open(file_name_.c_str());
    }
    

    Wieder nicht RAII -.-

    parser::parser(std::string file_name_) : file(file_name_c.c_str()) {}
    

    So UND NICHT ANDERS ist es korrekt.



  • 314159265358979 schrieb:

    So UND NICHT ANDERS ist es korrekt.

    Ziemlich harte Aussage. Schon mal an Lazy Evaluation gedacht?



  • Was hat das mit Lazy Evaluation zu tun?



  • theliquidwave schrieb:

    Es bringt das Programm aber auch nicht zum Absturz

    Das tut ;;;;;;;;;;;;;;;;;;;;;;;;;;;; auch nicht.

    oder hat sonstige negative Effekte.

    Die hat es sehr wohl. Code wird unnötig kompliziert und macht den Eindruck, als würde man den Filestreams nicht vertrauen und deshalb wie in Java explizit schliessen. Man ignoriert eingebaute Mechanismen. Beim Überfliegen des Codes kommt das Gefühl zustande, dass nur an einem Ort geschlossen würde, während RAII aber bei jedem Verlassen des Scopes zum Zug kommt. Ausserdem ist close() dafür konzipiert, Dateien vorzeitig zu schliessen, und nicht wenn sie ohnehin geschlossen werden.

    Klar, ein close() ist nicht schlimm – aber das gilt für viele Dinge. Tatsache ist, dass close() unnötig ist und bei konsequentem Einsatz (d.h. überall wo RAII zum Zug käme) Code kompliziert macht. Bei nicht-konsequentem Einsatz bringt es ohnehin nichts.



  • Schon, dennoch finde ich es übersichtlicher, die Datei zu schließen (eben mit .close() ). Aber das ist - wie so oft - Ansichtssache. Ich sehe nichts falsches darin.



  • wer output streams nicht mit close schließt, kann auch nicht prüfen, ob alles geschrieben wurde.



  • Hey Leute!

    Vielen Dank für die Hilfe. ...und sorry - so eine Diskussion wollte ich wirklich nicht auslösen!
    Vielleicht ist es gerade gut zu Ablenkung: Mein Code hat immernoch gewisse Fehler. Ich habe sie widerum im Code kommentiert. (evtl. habe ich Eure Vorschläge auch falsch umgesetzt...)

    .cpp class:

    #include <iostream>
    
    #include <fstream>
    #include "parser.hpp"
    #include "person.hpp"
    #include <vector>
    #include <iterator>
    
    std::vector<person> _ausgabe; 
    
    parser::parser(std::string file_name_)
    {
       	std::ifstream file(file_name_.c_str());
    }
    
    void 
    	parser::parse(void)
    {
    	if(!file.is_open()) //hier wird mir ein Fehler angezeigt wegen "file", der nicht deklariert ist..
    	{
    		std::cerr << "Konnte Datei nicht oeffnen." << file_name_ << std::endl; //ebenfalls wieder wegen "file"...
    		return;
    	}
    
    	_ausgabe.clear();
    
    	while(file.good()) //"file"...
    {
    	std::string surname;
    	std::string name;
    	std::string number;
    
    	file >> surname;
    	file >> name;
    	file >> number;
    
    	if(file.good())
    	{
    		_ausgabe.push_back(person(surname, name, number));
    	}
    
    file.close();
    
    }
    }
    
    void
    parser::print(void)
    {
       	int total = 0;
    	std::vector<int>::iterator the_iterator = _ausgabe.begin(); // kann es sein, dass man _ausgabe nicht so verwenden darf/kann? Wie wäre es richtig?
    
    	while(the_iterator != _ausgabe.end() ) // hier stimmt was mit "!=" nicht, aber ich vermute eher, dass es am "_ausgabe" liegt.
    	{
    		total += *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    
    void
    parser::print_reverse(void)
    {
    	std::vector<int> the_vector;
    	for(int i = the_vector.size(); i >= 0; i--)
    	{
    		the_vector.push_back(i);
    	}
    }
    

    .hpp-file:

    #ifndef PARSER_H
    #define PARSER_H
    
    #include "person.hpp"
    
    #include <string>
    #include <vector>
    
    class parser
    {
    
        public:
            parser(std::string file_name_);
    
            void
            parse(void);
    
            void
            print(void);
    
            void
            print_reverse(void);
    
        private:
            std::string _file_name;
    
            std::vector<person> _persons;
    
    		parser::parser(std::string file_name_) 
    		{ 
    			file.open(file_name_.c_str());
    		} 
    		// oder:
    		// parser::parser(std::string file_name_) : file(file_name_c.c_str()) {}
    
    };
    
    #endif  // PARSER_H
    


  • und schrieb:

    wer output streams nicht mit close schließt, kann auch nicht prüfen, ob alles geschrieben wurde.

    Und das interessiert wen?



  • 314159265358979 schrieb:

    und schrieb:

    wer output streams nicht mit close schließt, kann auch nicht prüfen, ob alles geschrieben wurde.

    Und das interessiert wen?

    Schreiboperationen können immer mal fehlschlagen (Abstecken der USB-Platte etc.), bevor man irgendein Dirty-Flag löscht, ist es eigentlich Pflicht, den Erfolg der Operation überprüft zu haben...



  • Ach ja, @MAXC++: file ist kein Member deiner Klasse parser.



  • flush + anschließendes prüfen.


Anmelden zum Antworten