Parsing



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



  • ..und wie deklariert man das in der Klasse?
    (also dass file ein Member ist)?



  • 314159265358979 schrieb:

    flush + anschließendes prüfen.

    LOL. Aber bloß nicht close aufrufen, da ist flush schon viel besser, weil wir ja super RAII sind... 🙄



  • 314159265358979 schrieb:

    Was hat das mit Lazy Evaluation zu tun?

    Wenn das Erstellen des Parse-Objekts und der eigentliche Parse-Vorgang zeitlich auseinander liegen, hälst du unnötig lange das File Handle. Vielleicht wird auch ein Parse-Objekt erstellt, aber nie die entsprechende Datei geparst.



  • lollerchen schrieb:

    314159265358979 schrieb:

    flush + anschließendes prüfen.

    LOL. Aber bloß nicht close aufrufen, da ist flush schon viel besser, weil wir ja super RAII sind... 🙄

    true



  • Hey Leute..ich kann zwar bei eurer Diskussion nicht mitreden, wollte aber trotzdem fragen, ob mir evtl. jemand meine Fragen (siehe Code) beantworten könnte?
    ..da wäre ich wirklich sehr dankbar!



  • MAXc++ schrieb:

    ..und wie deklariert man das in der Klasse?
    (also dass file ein Member ist)?

    Ich würde das an deiner Stelle in deinem C++-Buch nachlesen. Wie Klassen aufgebaut sind und wie Member deklariert werden, wird da sicher beschrieben. Wir können dir jetzt hier schon eine spezifische Antwort geben, aber dann ist dein nächstes Problem garantiert nicht weit.

    Lieber, du schaust dir die Theorie dazu richtig an, dann hast du auch nicht nur Halbwissen (vorausgesetzt dein Buch ist brauchbar) 😉



  • Vicious Falcon schrieb:

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

    Wurde es doch.


Anmelden zum Antworten