Hausaufgaben Verwaltungs Programm



  • Ich werde es nicht kopieren, versprochen!
    Nur könntest du vielleicht ein paar Kommentare hinter dem Sourcecode geben damit ich weiß wo was zu da ist? Ich versteh bis jetzt nämlich fast gar nix!



  • Hmm ja kein Problem ... welche Funktion verstehst du denn nicht? Die zum Speicher/Laden? 😉 Oder welche?



  • Ja, also die Speicher Funktion und die Delete Funktion



  • Na dann ... fangen wir mal an ^^

    bool HomeworkManager::write_file(const std::string& filename)
    {
        std::ofstream file_stream; // Das ist ein sog. File-Stream ...
        file_stream.open(filename.c_str(), std::ios::out | std::ios::binary); // Damit öffnen wir die Datei, 
        // die in filename hinterlegt ist und zwar im std::ios::out mode, da wir ja schreiben wollen ... und dann nor std::ios::binary, 
        // da wir es binär schreiben wollen ...
    
        if (file_stream.is_open() == false || file_stream.good() == false) // Das ist nur Fehlerüberprüfung ob das 
        // Öffnen Funktionier hat ...
            return false;
    
        // Hier hab ich dir nur aufgeschrieben, wie die Datei strukturiert ist bzw aufgebaut ist.
        // File Content:
        //        size_t                Subject Count
        //        size_t                Item Count
        //        Item:
        //            time_t                time
        //            size_t                string_len
        //            char[string_len]    work
        //            unsigned short        subject
        //        Subject:
        //            size_t                string_len
        //            char[string_len]    subject
    
        size_t subject_count = m_subjects.size(); // Erstmal die Anzahl an Fächern holen
        file_stream.write(reinterpret_cast<char*>(&subject_count), sizeof(size_t)); // Das dann in die Datei schreiben ...
        if (file_stream.good() == false) // Alles ok?
            return false;
    
        size_t works_count = m_works.size(); // Das selbe für die Anzahl an Hausaufgaben ...
        file_stream.write(reinterpret_cast<char*>(&works_count), sizeof(size_t));
        if (file_stream.good() == false)
            return false;
    
        for (size_t item = 0; item < works_count; ++item) // Alle Hausaufgaben durchgehen ...
        {
            char*    item_work        = const_cast<char*>(m_works[item].work.c_str()); // Da c_str einen const char* zurück gibt ... wir aber nur einen char* 
            // gebrauchen können, müssen wir das const wegcasten ...
            size_t    item_work_len    = m_works[item].work.length(); // Die Länge des Strings holen ... brauchen wir beim
            // Einlesen wieder ...
            file_stream.write(reinterpret_cast<char*>(&m_works[item].timestamp), sizeof(time_t)); // Den Zeitpunkt abspeichern
            file_stream.write(reinterpret_cast<char*>(&item_work_len), sizeof(size_t)); // Jetzt die Länge des Strings reinpacken ...
            file_stream.write(item_work, item_work_len); // den String selbst auch ...
            file_stream.write(reinterpret_cast<char*>(&m_works[item].subject), sizeof(unsigned short)); // und am Ende noch welches Fach es ist ...
    
            if (file_stream.good() == false) // War das alles erfolgreich?
                return false;
        }
    
        for (size_t item = 0; item < subject_count; ++item) // Alle Fächer durchgehen
        {
            char*    item_subject        = const_cast<char*>(m_subjects[item].c_str()); // wieder const wegcasten
            size_t    item_subject_len    = m_subjects[item].length(); // die lenge des Fachnamens holen ...
            file_stream.write(reinterpret_cast<char*>(&item_subject_len), sizeof(size_t)); // Rein in die Datei damit ...
            file_stream.write(item_subject, item_subject_len); // und der String selbst kommt hinterher ...
        }
    
        file_stream.close(); // Den Stream schließen ...
    
        return true;
    }
    

    So ...

    // File Content:
    // size_t Subject Count
    // size_t Item Count
    // Item:
    // time_t time
    // size_t string_len
    // char[string_len] work
    // unsigned short subject
    // Subject:
    // size_t string_len
    // char[string_len] subject

    Durch diesen Ansatz bist du unabhängig davon was du wann für Fächer registrierst ... denn am Anfang holt der sich beim Laden erstmal wieder die Fächer mit denen die Hausaufgaben erstellt worden sind ...
    Subject Count und Item Count hab ich mit rein getan, weil die das Auslesen nachher ungemein vereinfachen ... da du so weißt wie Lang dein Hausaufgaben und dein Fächer - Block ist ...
    string_len schreiben wir auch mit rein, da wir ja nicht wissen können, wie lang denn der darauf folgende String wohl sein wird ... weil std::string ja nicht ne feste Größe hat ...



  • Oben ist ja mein jetziger Sourcecode angegeben, und irgendwie merke ich grade das

    #include <iostream>
    #include <string>
    #include <sstream>
    #include "homeworkmanager.h"
    
    int main()
    {
        HomeworkManager manager("test.svf");
        /* Das nur beim 1. mal ausführen ... danach rausnehmen, da auch die Fächer aus der Datei ausgelesen werden ... das erlaubt dir bsw dem User eine Funktion zum hinzufügen von eigenen Fächern zu bieten ...
        manager.add_subject("Deutsch");
        manager.add_subject("Physik");
        manager.add_subject("Mathematik");
        */
    
        std::cout << "-\t\tHomeworkManager V0.1\t\t-" << std::endl;
        unsigned short selection = 0;
        unsigned short menu_item_count = 0;
        do
        {
            menu_item_count = 0;
            std::cout << "* Menu" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Add new item" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Show items" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Sort" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Mark as done!" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Exit" << std::endl;
    
            std::istringstream ss;
            std::string string_input;
    
            do {
                std::cout << "\tInput: " << std::flush;
                std::getline(std::cin, string_input);
                ss.clear();
                ss.str(string_input);
                ss >> selection;
            } while (!ss || selection > menu_item_count);
    
            switch (selection)
            {
            case 1:
                {
                    std::cout << "* New entry: " << std::endl;
                    manager.list_subjects();
                    work_entry entry;
                    do {
                        std::cout << "\n\tSubject: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> entry.subject;
                    } while (!ss);
                    std::cout << "\tWork: " << std::flush;
                    std::getline(std::cin, entry.work);
                    entry.timestamp = time(NULL);
                    manager.insert_item(entry);
                } break;
            case 2:
                {
                    std::cout << "* Show Item: " << std::endl;
                    std::cout << "\t(-1) All Items" << std::endl;
                    std::cout << "\t(x) Item number" << std::endl;
                    short item = -1;
                    do {
                        std::cout << "\n\tInput: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> item;
                    } while (!ss || item < -1);
                    manager.show_item(item);
                    manager.sort(false);
                } break;
            case 3:
                {
                    std::cout << "* Sort: " << std::endl;
                    std::cout << "\t(0) Ascending" << std::endl;
                    std::cout << "\t(1) Descending" << std::endl;
                    bool sort = false;
                    do {
                        std::cout << "\tInput: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> sort;
                    } while (!ss);
                    manager.sort(!sort);
                } break;
            case 4:
                {
                    std::cout << "* Mark as done: " << std::endl;
                    unsigned short id = 0;
                    do {
                        std::cout << "\tItem-ID: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> id;
                    } while (!ss);
                    manager.delete_item(--id);
                } break;
            }
        } while (selection != menu_item_count);
        return 0;
    }
    

    gar nicht mehr auf meinen Aufbaut, hab ich da recht?

    Gruß
    Manuh



  • Hmm ... naja ich hab es halt so gemacht, das ich 1. nicht immer gucken muss, wie viele Menüeinträge ich jetzt hab und dem entsprechend die Zahl die fürs schließen da ist anzugeben ...

    case 2:
                {
                    std::cout << "* Show Item: " << std::endl;
                    std::cout << "\t(-1) All Items" << std::endl;
                    std::cout << "\t(x) Item number" << std::endl;
                    short item = -1;
                    do {
                        std::cout << "\n\tInput: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> item;
                    } while (!ss || item < -1);
                    manager.show_item(item);
                    manager.sort(false);
                } break;
            case 3:
                {
                    std::cout << "* Sort: " << std::endl;
                    std::cout << "\t(0) Ascending" << std::endl;
                    std::cout << "\t(1) Descending" << std::endl;
                    bool sort = false;
                    do {
                        std::cout << "\tInput: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> sort;
                    } while (!ss);
                    manager.sort(!sort);
                } break;
    

    ... Das sollte bei dir auch gehen ... die sort Funktion der HomeworkManager klasse ist ja vorhanden ... und hab halt da bei deren Menü 0 und 1 genommen ... weil man daraus boolsche werte machen kann ... und die show_item funktion ist auch vorhanden ... und wenn der -1 übergeben wird, wird ja alles angezeigt ... andernfalls wird halt das element angezeigt, was du angeben hast ... und das hab ich nur für den Benutzer zugänglich gemacht ...



  • Wenn ich nun eine Hausaufgabe löschen möchte, bleibt das Programm immer stehen und ein Sofort Beenden bildschirm öffnet sich, weiß jemand wieso?

    Gruß
    manuh



  • Ja ... hast de evt. auf nen falschen Speicherbereich zugegriffen? Zeig mal wie du das löschst ... und guck dir notfalls mal meinen dazu passenden Code an ...



  • Iksde schrieb:

    [...]
    bool my_sort_asc(const work_entry& l, const work_entry& r)
    {
    return l.timestamp < r.timestamp;
    }

    bool my_sort_desc(const work_entry& l, const work_entry& r)
    {
    return l.timestamp > r.timestamp;
    }

    [...]

    unsigned short selection = 0;

    [...]

    Warum das "= 0" in der Deklaration von selection?

    Wäre es nicht besser aus den Funktionen Operatoren zu machen?



  • Ich habe deinen Code jetzt benutzt, habe mir erst angeschaut wie das Programm aufgebaut ist, und dann habe ich das kopiert und angepasst,
    hier nochmal:

    Hausaufgaben.cpp

    #include <iostream>
    #include <string>
    #include <sstream>
    #include "homeworkmanager.hpp"
    
    int main()
    {
        HomeworkManager manager("Stundenplan.svf");
    
        std::cout << "-\t\tHausaufgaben Manager V0.1\t\t-" << std::endl;
        unsigned short selection = 0;
        unsigned short menu_item_count = 0;
        do
        {
            menu_item_count = 0;
            std::cout << "* Menu" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Neue Hausaufgaben" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Hausaufgaben anzeigen" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Sortieren" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Als erledigt markieren!" << std::endl;
            std::cout << "\t(" << ++menu_item_count << ") Beenden" << std::endl;
    
            std::istringstream ss;
            std::string string_input;
    
            do {
                std::cout << "\tEingabe: " << std::flush;
                std::getline(std::cin, string_input);
                ss.clear();
                ss.str(string_input);
                ss >> selection;
            } while (!ss || selection > menu_item_count);
    
            switch (selection)
            {
            case 1:
                {
                    std::cout << "* Neuer Eintrag: " << std::endl;
                    manager.list_subjects();
                    work_entry entry;
                    do {
                        std::cout << "\n\tFach: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> entry.subject;
                    } while (!ss);
                    std::cout << "\tHausaufgabe: " << std::flush;
                    std::getline(std::cin, entry.work);
                    entry.timestamp = time(NULL);
                    manager.insert_item(entry);
                } break;
            case 2:
                {
                    std::cout << "* Hausaufgaben anzeigen: " << std::endl;
                    std::cout << "\t(-1) Alle Hausaufgaben" << std::endl;
                    std::cout << "\t(x) Fach Nummer" << std::endl;
                    short item = -1;
                    do {
                        std::cout << "\n\tEingabe: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> item;
                    } while (!ss || item < -1);
                    manager.show_item(item);
                    manager.sort(false);
                } break;
            case 3:
                {
                    std::cout << "* Sortieren: " << std::endl;
                    std::cout << "\t(0) Aufsteigend" << std::endl;
                    std::cout << "\t(1) Absteigend" << std::endl;
                    bool sort = false;
                    do {
                        std::cout << "\tEingabe: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> sort;
                    } while (!ss);
                    manager.sort(!sort);
                } break;
            case 4:
                {
                    std::cout << "* Als erledigt Markieren: " << std::endl;
                    unsigned short id = 0;
                    do {
                        std::cout << "\tFach ID: " << std::flush;
                        std::getline(std::cin, string_input);
                        ss.clear();
                        ss.str(string_input);
                        ss >> id;
                    } while (!ss);
                    manager.delete_item(--id);
                } break;
            }
        } while (selection != menu_item_count);
        return 0;
    }
    

    HomeWorkManager.h

    #if !defined(HOMEWORK_MANAGER_H__INCLUDED)
    #define HOMEWORK_MANAGER_H__INCLUDED
    
    #pragma once
    
    #include <iostream>
    #include <vector>
    #include <string>
    #include <algorithm>
    #include <ctime>
    #include <fstream>
    
    struct work_entry
    {
        unsigned short    subject;
        time_t            timestamp;
        std::string        work;
    
        work_entry() : subject(0), timestamp(0) {}
    };
    
    class HomeworkManager
    {
    public:
        HomeworkManager(const std::string&);
        ~HomeworkManager();
    
    public:
        void insert_item(const work_entry&);
        void show_item(const short); // -1 == all entrys
        bool delete_item(const unsigned short&);
    
    public:
        void add_subject(const std::string&);
        void list_subjects(void);
    
    public:
        void sort(const bool);
    
    public:
        bool read_file(const std::string&);
        bool write_file(const std::string&);
    
    private:
        std::vector<work_entry>        m_works;
        std::vector<std::string>        m_subjects;
        const std::string            m_filename;
    };
    
    #endif // HOMEWORK_MANAGER_H__INCLUDED
    

    HomeworkManager.hpp

    #include "HomeworkManager.h"
    
    HomeworkManager::HomeworkManager(const std::string& filename) : m_filename(filename)
    {
        read_file(m_filename);
    }
    
    HomeworkManager::~HomeworkManager(void)
    {
        write_file(m_filename);
    }
    
    void HomeworkManager::insert_item(const work_entry& entry)
    {
        m_works.push_back(entry);
    }
    
    void HomeworkManager::show_item(const short id)
    {
        if (id == -1)
        {
            for (size_t item = 0; item < m_works.size(); ++item)
                std::cout << "ID: " << (item + 1) << " :: " << m_works[item].timestamp << " | " << m_works[item].work << " | " << (m_works[item].subject > m_subjects.size() ? "Unknown" : m_subjects[m_works[item].subject - 1]) << std::endl;
        }
        else if (id > 0 && static_cast<unsigned short>(id) < m_works.size())
        {
            std::cout << m_works[id].timestamp << " | " << m_works[id].work << " | " << (m_works[id].subject > m_subjects.size() ? "Unknown" : m_subjects[m_works[id].subject - 1]) << std::endl;
        }
    }
    
    bool my_sort_asc(const work_entry& l, const work_entry& r)
    {
        return l.timestamp < r.timestamp;
    }
    
    bool my_sort_desc(const work_entry& l, const work_entry& r)
    {
        return l.timestamp > r.timestamp;
    }
    
    void HomeworkManager::sort(const bool ascending)
    {
        std::sort(m_works.begin(), m_works.end(), (ascending == true ? my_sort_asc : my_sort_desc));
    }
    
    void HomeworkManager::add_subject(const std::string& subject)
    {
        m_subjects.push_back(subject);
    }
    
    void HomeworkManager::list_subjects(void)
    {
        std::cout << "* Subjects: " << std::endl;
        for (size_t item = 0; item < m_subjects.size(); ++item)
            std::cout << "\t" << (item + 1) << ": " << m_subjects[item] << std::endl;
    }
    
    bool HomeworkManager::write_file(const std::string& filename)
    {
        std::ofstream file_stream;
        file_stream.open(filename.c_str(), std::ios::out | std::ios::binary);
    
        if (file_stream.is_open() == false || file_stream.good() == false)
            return false;
    
        // File Content:
        //        size_t                Subject Count
        //        size_t                Item Count
        //        Item:
        //            time_t                time
        //            size_t                string_len
        //            char[string_len]    work
        //            unsigned short        subject
        //        Subject:
        //            size_t                string_len
        //            char[string_len]    subject
    
        size_t subject_count = m_subjects.size();
        file_stream.write(reinterpret_cast<char*>(&subject_count), sizeof(size_t));
        if (file_stream.good() == false)
            return false;
    
        size_t works_count = m_works.size();
        file_stream.write(reinterpret_cast<char*>(&works_count), sizeof(size_t));
        if (file_stream.good() == false)
            return false;
    
        for (size_t item = 0; item < works_count; ++item)
        {
            char*    item_work        = const_cast<char*>(m_works[item].work.c_str());
            size_t    item_work_len    = m_works[item].work.length();
            file_stream.write(reinterpret_cast<char*>(&m_works[item].timestamp), sizeof(time_t));
            file_stream.write(reinterpret_cast<char*>(&item_work_len), sizeof(size_t));
            file_stream.write(item_work, item_work_len);
            file_stream.write(reinterpret_cast<char*>(&m_works[item].subject), sizeof(unsigned short));
    
            if (file_stream.good() == false)
                return false;
        }
    
        for (size_t item = 0; item < subject_count; ++item)
        {
            char*    item_subject        = const_cast<char*>(m_subjects[item].c_str());
            size_t    item_subject_len    = m_subjects[item].length();
            file_stream.write(reinterpret_cast<char*>(&item_subject_len), sizeof(size_t));
            file_stream.write(item_subject, item_subject_len);
        }
    
        file_stream.close();
    
        return true;
    }
    
    bool HomeworkManager::read_file(const std::string& filename)
    {
        std::ifstream file_stream;
        file_stream.open(filename.c_str(), std::ios::in | std::ios::binary);
    
        if (file_stream.is_open() == false || file_stream.good() == false)
            return false;
    
        size_t subject_count = 0;
        file_stream.read(reinterpret_cast<char*>(&subject_count), sizeof(size_t));
        if (file_stream.good() == false)
            return false;
        m_subjects.reserve(subject_count);
    
        size_t works_count = 0;
        file_stream.read(reinterpret_cast<char*>(&works_count), sizeof(size_t));
        if (file_stream.good() == false)
            return false;
        m_works.reserve(works_count);
    
        for (size_t item = 0; item < works_count; ++item)
        {
            size_t            item_work_len    = 0;
            work_entry        entry;
    
            file_stream.read(reinterpret_cast<char*>(&entry.timestamp), sizeof(time_t));
            file_stream.read(reinterpret_cast<char*>(&item_work_len), sizeof(size_t));
            char * item_work = new char [item_work_len + 1];
            file_stream.read(item_work, item_work_len);
            item_work[item_work_len] = '\0';
            file_stream.read(reinterpret_cast<char*>(&entry.subject), sizeof(unsigned short));
    
            entry.work = item_work;
            m_works.push_back(entry);
            delete [] item_work;
    
            if (file_stream.good() == false)
                return false;
        }
    
        for (size_t item = 0; item < subject_count; ++item)
        {
            size_t    item_subject_len    = 0;
            file_stream.read(reinterpret_cast<char*>(&item_subject_len), sizeof(size_t));
            char* item_subject = new char [item_subject_len + 1];
            file_stream.read(item_subject, item_subject_len);
            item_subject[item_subject_len] = '\0';
            std::string item_string(item_subject);
            m_subjects.push_back(item_string);
            delete [] item_subject;
        }
    
        file_stream.close();
    
        return true;
    }
    
    bool HomeworkManager::delete_item(const unsigned short& id)
    {
        std::vector<work_entry>::iterator it = m_works.begin() + (id - 1);
        m_works.erase(it);
        return true;
    }
    

    Gruß
    Manuh



  • *push up*


Anmelden zum Antworten