Aus .txt Datei lesen



  • Hier is der Code nochma, bissel umgeändert, aufgeteilt und noch bissel verpackt....
    main.cpp

    #include "text_editor.hpp"
    
    int main()
    {
        text_editor program;
        while(program.menu());
    
        return 0;
    }
    

    text_editor.hpp

    #ifndef TEXT_EDITOR_HPP_INCLUDED
    #define TEXT_EDITOR_HPP_INCLUDED
    
    #include <iostream>
    #include <string>
    
    class read
    {
        public:
        read(const std::string &file_name_);
        bool readout(std::ostream &ios_object) const;
    
        private:
        const std::string m_file_name;
    };
    
    class write
    {
        public:
        write(const std::string &file_name_);
        bool fill_in(bool remove);
    
        private:
        const std::string m_file_name;
    
    };
    
    //Macht die Klassen "read" und "write" Benutzerfreundlicher
    class text_editor
    {
        public:
        text_editor();
        bool menu();
        bool handle_file_write() const;
        bool handle_file_read() const;
        void error_message(const std::string &message);
    
        private:
        bool m_remove;
    
    };
    
    #endif // TEXT_EDITOR_HPP_INCLUDED
    

    text_editor.cpp

    #include <iostream>
    #include <fstream>
    #include <conio.h>
    #include "text_editor.hpp"
    #include "ic.hpp" //Improved Konsole
    
    using namespace std;
    using namespace ic; //Improved Konsole
    
    //KLASSE READ
    read::read(const std::string &file_name_)
    :m_file_name(file_name_)
    {
    
    }
    
    //Methode um Datein auszulesen
    bool read::readout(ostream &ios_object) const
    {
        ifstream file(m_file_name.c_str()); //<-- Streamobjekt "file"
        if(!file) return false; //Stream fehlerhaft?
        if(!ios_object) return false; //Objekt Fehlerhaft?
        string buffer;
        while(getline(file,buffer))
        {
            ios_object << buffer << "\n";
        }
        //<-- Ab hier wird "file" false!!! Warum?
        file.clear(); //Kann das nur mit dem hier beheben, sonst wird text_editor::message_error() aufgerufen
                      //Aber ist ja auch bissel gemogelt wenn ich dann einfach alles wieder "clear()" mache.
                      //Aber was hat "file" hier für ein Problem?
        cout << file << endl;
        getch();
        return file;
    }
    
    //KLASSE WRITE
    write::write(const std::string &file_name_)
    :m_file_name(file_name_)
    {
    
    }
    
    bool write::fill_in(bool remove)
    {
        ofstream file;
        if(remove) file.open(m_file_name.c_str()); //Datei wird immer neu erstellt
        else file.open(m_file_name.c_str(), ios::out | ios::app); //In Datei weiter schreiben
    
        if (!file) return false;
        string buffer;
        while(getline(cin,buffer))
        {
            if(buffer == "exit") return true;
            file << buffer << "\n";
        }
        return file;
    }
    
    //KLASSE TEXT_EDITOR
    text_editor::text_editor()
    :m_remove(false)
    {
    }
    
    bool text_editor::menu()
    {
        short input;
        cout << "< 1 > Datei beschreiben\n";
        cout << "< 2 > Datei lesen\n";
        cout << "< 3 > Programm beenden\n";
    
        cout << "\n\n\n### OPTIONEN ###\n\n";
        cout << "< 4 > Beim beschreiben Datei immer neuerstellen";
        if(m_remove) cout << " 'AN'\n";
        else cout << " 'AUS'\n";
    
        cout << "\n\n\n--> ";
        cin >> input;
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(),'\n');
    
        //Bildschirm löschen | Cursor Poition nach oben
        con.clearColor(BG_BLACK);
        con.setCurPos(0,0);
    
        switch(input)
        {
            case 1:
            if(!handle_file_write()) error_message("Das Beschreiben musste beendet werden.\n");
            break;
            case 2:
            if(!handle_file_read()) error_message("Das Lesen musste beendet werden.\n") ;
            break;
            case 3:
            return false;
            break;
            case 4:
            if(m_remove) m_remove=false;
            else m_remove=true;
            break;
        }
    
        //Bildschirm löschen | Cursor Poition nach oben
        con.clearColor(BG_BLACK);
        con.setCurPos(0,0);
    
        return true;
    }
    
    bool text_editor::handle_file_write() const
    {
        string save_name;
        cout << "Dateiname: ";
        getline(cin,save_name);
        cout << "'exit' am Zeilenanfang + 'ENTER' = Schreibprogramm wird beendet\n\n";
        write t_e_write(save_name);
        return t_e_write.fill_in(m_remove);
    }
    
    bool text_editor::handle_file_read() const
    {
        string save_name;
        cout << "Dateiname: ";
        getline(cin,save_name);
        cout << "Beliebiger Tastendruck = Leseprogramm wird beendet\n\n";
        read t_e_read(save_name);
        return t_e_read.readout(cout);
    }
    
    //Fehlermeldung, wenn ein stream "false" zurückgibt
    void text_editor::error_message(const string &message)
    {
        //Bildschirm löschen | Cursor Poition nach oben
        con.clearColor(BG_BLACK);
        con.setCurPos(0,0);
    
        cout << "Ein Problem wurde festgestellt!\n";
        cout << message;
        getch();
    }
    

    Was haltet ihr davon?

    Hab noch ein Problem, meine Methode "readout" gibt immer "false" zurück, wodurch ein Error aufgerufen wird. Das liegt daran dass das Streamobjekt "file" plötzlich nach der while Schleife false ist, obwohls vorher noch true war....
    [siehe: text_editor.cpp, Zeile 29]
    Die Datei wird super eingelesen, alles...richtig aufm Bildschirm der Text ausgegeben...passt alles, nur das "file" dann "false" ist, und dadurch "false" von der Methode "readout" zurück gegeben wird, und dadurch wird wiederum die "Error Methode" aufgerufen!!!! Ich versteh aber einfach nicht warum diese verdammte Streamobjekt "false" wird?!!!
    Vll. blickt da eienr von euch besser durch.

    MfG
    Stromberg



  • Du liest in readout solange mit getline ein bis die false zurückliefert. Dies ist dann der Fall wenn nichts mehr gelesen werden kann, also am Dateiende. Da wird aber dann auch eof() gesetzt und file liefert somit false zurück.
    Die Lösung mit clear ist da schon ok evtl. kannst du ja noch den Filepointer auf den Anfang zurück setzten.



  • bool write::fill_in(bool remove)
    {
        ofstream file;
        if(remove) file.open(m_file_name.c_str()); //Datei wird immer neu erstellt
        else file.open(m_file_name.c_str(), ios::out | ios::app); //In Datei weiter schreiben
    
        if (!file) return false;
        string buffer;
        while(getline(cin,buffer))
        {
            if(buffer == "exit") return true;
            file << buffer << "\n";
        }
        return file;
    }
    

    nicht so perfekt 😉

    bool write::fill_in(std::istream& in = std::cin, bool empty = true)
    {
        std::ofstream file_stream(m_file_name.c_str(), empty == true ? std::ios::out : std::ios::app);
        if (!file_stream) return false;
    
        std::string buffer;
        while (std::getline(in, buffer) && buffer != "exit")
            file_stream << buffer << "\n";
    
        return file_stream;
    }
    

    ... bei std::ofstream ist standardmäßig std::ios::out drin. kannst es hier in dem Fall für den einfachen Vergleich aber misbrauchen 😉 Und die Schleife kannst du auch verkürzen (s. Code) und statt return true hättest du sonst auch lieber gucken sollen ob file_stream einen Fehler gefunden hat 😉

    //Methode um Datein auszulesen
    bool read::readout(std::ostream& out) const
    {
        if (!out) return false; // sonst wird hier noch das std::ifstream Objekt erzeugt! ...
    
        std::ifstream file_stream(m_file_name.c_str());
        if (!file_stream) return false;
    
        std::string buffer;
        while (std::getline(file_stream, buffer))
            out << buffer << "\n";
    
        return true;
    }
    


  • Heißt das hier:

    ...empty == true ? std::ios::out : std::ios::app);
    

    soviel wie "wenn empty true ist, dann setzte als Parameter "std::ios::out : std::ios::app", wenn nicht dann setz einfach nichts (also halt default Parameter)?
    Das sowas geht, wusste ich anfangs nicht, weil ich hab das erst so gemacht:

    if(remove) ofstream file(.....);
    else ofstream file(.....,.....);
    

    Aber is ja Unsinn, weil des wird ja nur innerhlab des if-Scope deklariert, und verliert außerhalb dann seine Wertigkeit.
    Und des halb hab ich das mit dem ".open"....gemacht..aber is ja alles schlecht, des von dir is natürlich um einiges besser.
    MfG
    Stromberg



  • nein, es bedeutet "wenn empty true ist, dann setze als parameter ios::out, andernfalls ios::app" (':' bedeutet andernfalls)

    abgesehen davon sollte man mit boolschen werten keine vergleiche machen (weil es ohne auch geht)



  • Ja, aber wie kann n das gehen, wenn empty "true" ist, dann wird "ios::out" gesetzt. Verstehe ich noch, aber wenn empty "false" ist, dann wird ja "ios::app" gesetzt, aber das muss doch immer "ios::out | ios::app" heißen, nicht nur "ios::app"?
    Wie nennt man n das eigentlich ":" und "?" Vergleichsoperatoren für Parameter oder was... hab davon igrendwie noch nie was mitbekommen 😞
    Hat jemand einen Link wo da noch bissel ins Detail gegangen wird, oder kann man da nich mehr viel ins Detail gehen?
    Also ich mein mit if kann ich schon umgehen....aber die dinger da hab ich irgendwien icht gekannt.
    MfG
    Stromberg



  • sollte es, ja.

    das "ding" ?: nennt sich der "ternäre operator", der einzige operator mit drei operanden, der außerdem nicht überladen werden kann.



  • Also setzte er dann noch "ios::out" automatisch zu "ios::app" dazu oder wie?
    MfG
    Stromberg



  • Naja du hast schon recht, theoretisch steht da bei empty == false nur ein std::ios_base::app. Doch da du einen std::ofstream gewählt hast, ist automatisch std::ios_base::out gesetzt 😉 Kannst auch empty == true ? 0 : std::ios_base::app nehmen, sollte auch gehen.



  • ja, so geht es auch. es funktioniert nur dann nicht mehr, wenn du den ofstream gegen einen fstream austauschst.


Anmelden zum Antworten