Parsing



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



  • Hallo miteinander!

    So, mittlerweile sieht mein Code wie folgt aus:

    #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)
    {
    
       	std::ifstream file(parser._file_name);
    
    	if(!file.is_open()) 
    	{
    		std::cerr << "Konnte Datei nicht oeffnen." << _file_name << std::endl;
    	}
    
    	_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::print(void)
    {
        	std::vector<person> _ausgabe;
    	for(int i = 0; i <= _ausgabe.size(); i++)
    	{
    		_ausgabe.push_back(i);
    	}
    
    	int total = 0;
    	std::vector<person>::iterator the_iterator = _ausgabe.begin();
    	while(the_iterator != _ausgabe.end())
    	{
    		total = total + *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    
    void
    parser::print_reverse(void)
    {
    	std::vector<person> _ausgabe;
    	for(int i = _ausgabe.size(); i >= 0; i--)
    	{
    		_ausgabe.push_back(i);
    	}
    
    	int total = 0;
    	std::vector<person>::iterator the_iterator = _ausgabe.begin();
    	while(the_iterator != _ausgabe.end())
    	{
    		total = total + *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    

    ..allerdings stimmen einige Sachen immer noch nicht:

    parser.hpp(44): error C2535: 'parser::parser(std::string)': Memberfunktion bereits definiert oder deklariert
    parser.hpp(45): error C2065: 'file': nichtdeklarierter Bezeichner
    arser.hpp(45): error C2228: Links von ".open" muss sich eine Klasse/Struktur/Union befinden.
    1>          Typ ist ''unknown-type''
    cpp(26): error C2143: Syntaxfehler: Es fehlt ')' vor '.'
    cpp(28): error C2065: 'file': nichtdeklarierter Bezeichner
    cpp(35): error C2065: 'file': nichtdeklarierter Bezeichner
    pp(35): fatal error C1903: Weiterverarbeitung nach vorherigem Fehler nicht möglich; Kompilierung wird abgebrochen.
    

    ..wozu ich 2 Fragen habe:
    a) Wie (konkret) kann ich diese Probleme endgültig fixen?
    b) Kann man eine der beiden print-Methoden auch ohne Iterator machen? Wenn ja, wie?



  • Hast du die Beiträge überhaupt gelesen? Du sollst file als Member der Klasse einrichten. Wenn du damit nichts anfangen kannst, lies das entsprechende Kapitel im Buch nach. Warum das mehr bringt als wenn wir dir die fertige Lösung posten, steht in meinem letzten Post.

    Die print() -Funktion könntest du auch mit Indizes implementieren, aber warum willst du auf Iteratoren verzichten?



  • Okay. Ich habe den Code nun soweit verändert, dass er meiner Meinung nach funktionieren müsste. Allerdings unterwellt mein Editor Dinge wie die Funktion parse und sagt, man dürfe die Funktion nicht ausserhalb der Klasse neu definieren. Was läuft schief? ..ich habe nun wirklich alles mehrmals überprüft, und sehe nicht, was falsch ist.
    Bei der .hpp-Klasse bin ich mir etwas unsicher, ob dort nicht was fehlt.
    Zudem habe ich den Inhalt von parser::parser gelöscht, wo eigentlich ein neuer Parser kreiert werden sollte. Das habe ich mit "new" probiert, allerdings gefiel das dem Compiler gar nicht.

    Ich wäre also wirklich froh, wenn mir jemand helfen könnte.
    Besten Dank im Voraus.

    .cpp:

    #include <iostream>
    
    #include <fstream>
    #include "parser.hpp"
    #include "person.hpp"
    #include <vector>
    #include <iterator>
    
    parser::parser(std::string file_name)
    {
        // ...	
    }
    
    void parser::parse(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;
    	}
    
    	_persons.clear();
    
    	while(file.good()) 
    {
    	std::string surname;
    	std::string name;
    	std::string number;
    
    	file >> surname;
    	file >> name;
    	file >> number;
    
    	if(file.good())
    	{
    		_persons.push_back(person(surname, name, number));
    	}
    
    file.close();
    
    }
    }
    
    void
    parser::print()
    {
     	for(int i = 0; i <= _persons.size(); i++)
    	{
    		_persons.push_back(i);
    	}
    
    	int total = 0;
    	std::vector<person>::iterator the_iterator = _persons.begin();
    	while(the_iterator != _persons.end())
    	{
    		total = total + *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    
    void
    parser::print_reverse(void)
    {
    	for(int i = _persons.size(); i >= 0; i--)
    	{
    		_persons.push_back(i);
    	}
    
    	int total = 0;
    	std::vector<person>::iterator the_iterator = _persons.begin();
    	while(the_iterator != _persons.end())
    	{
    		total = total + *the_iterator;
    		++the_iterator;
    	}
    
    	std::cout << total << std::endl;
    }
    

    .hpp:

    #ifndef PARSER_H
    #define PARSER_H
    
    #include "person.hpp"
    
    #include <string>
    #include <vector>
    
    class parser
    {
    
        public:
            /* create a new parser */
            parser(std::string file_name_);
    
            /* perform the parsing of the file */
            void
            parse(std::string _file_name);
    
            /* print using iterators */
            void
            print(void);
    
            /* reverse print using iterators */
            void
            print_reverse(void);
    
        private:
            /* name of the file to be parsed */
            std::string _file_name;
    
            /* vector containing found persons */
            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
    

    Übungshalber wollte ich mal probieren, ohne Iterators zu arbeiten. Der erste Anlauf missglückte zwar, aber das werd' ich dann nochmals probieren.


Anmelden zum Antworten