[Anfänger sucht Hilfe] Personalverwaltung - Datenerfassung und Ausgabe



  • SeppJ schrieb:

    struct PersonInfoStruct  // Ich würde bei Typennamen nicht angeben, dass es ein struct ist. Wozu soll das gut sein?
    {
      // Hier sollte man überlegen, ob die Attribute nicht lieber private sein sollten.
      std::string name;   // Vergiss char-Arrays, außer du hast einen sehr guten Grund
      std::string surname;
      float hours;
    };
    

    😕 Willst du dann für alle Member getter und setter machen, oder was hast du dir da genau vorgestellt?

    Wäre es nicht auch besser, statt float hours int minutes zu nehmen und zu Darstellungszwecken durch 60 zu teilen?


  • Mod

    out schrieb:

    😕 Willst du dann für alle Member getter und setter machen, oder was hast du dir da genau vorgestellt?

    Kommt auf die Anwendung an. Meine Klassen tun gewöhnlich etwas und sind nicht reine Datenhalden. Für reine Datenhalden bietet sich tatsächlich an, alles public zu machen. Für arbeitende Klassen 😉 sollte besser alles gekapselt sein, sonst pfuscht noch jemand von außen an den Interna herum.

    Wäre es nicht auch besser, statt float hours int minutes zu nehmen und zu Darstellungszwecken durch 60 zu teilen?

    Kommt auch auf die Anwendung an.



  • Hmm ich hab mal versucht das ganze zu verstehen, wenn ich das richtig sehe wird cin überladen und damit der Part für die Eingabe ausgelöst, oder?!

    Ist das so nötig, oder ist das nur zum verkürzen der Schreibarbeit?

    @Incocnito:
    Bei deinem Beispiel verstehe ich nicht ganz wie das mit dem vector läuft, der unter dem Namen "liste" auftaucht, dann ja aber nie genutzt wird, oder sehe ich das falsch? Du schreibst einfach in die Datei oder?

    AlphaX2



  • AlphaX2 schrieb:

    Hmm ich hab mal versucht das ganze zu verstehen, wenn ich das richtig sehe wird cin überladen und damit der Part für die Eingabe ausgelöst, oder?!

    Ist das so nötig, oder ist das nur zum verkürzen der Schreibarbeit?

    @Incocnito:
    Bei deinem Beispiel verstehe ich nicht ganz wie das mit dem vector läuft, der unter dem Namen "liste" auftaucht, dann ja aber nie genutzt wird, oder sehe ich das falsch? Du schreibst einfach in die Datei oder?

    AlphaX2

    Also erstmal wird cin nicht überladen, sondern nur der Eingabeoperator. Schau dir einfach mal "Operatorüberladung" an. Das spart in der Tat nur Schreibarbeit und sieht cooler aus. Eine Funktion ... operator >>(...) ist nur ne stinknormale Funktion wie jede andere, nur dass du halt Operatoren als Name und keine Buchtaben oder so verwendest. Kannst aber auch einfach eine Funktion void daten_einlesen(Person& p) oder sowas verwenden, wenn du das mit den Operatoren noch nicht checkst. Ist aber echt einfach.

    Und zu meinem Code: Der vector da ist tatsächlich erstmal unnötig. Ich hatte den da aber stehn, weil ich schon in Gedanken dabei war, Löschen und Ändern zu implementieren, das dann aber wohl einfach gelassen und dann vergessen hatte, die Zeile zu löschen. Ich wollte nämlich zum Löschen/Ändern aus der Datei die Personen einlesen, im vector zwischenspeichern, dann den vector bearbeiten und danach mit dem (neuen) Inhalt des vectors die Datei überschreiben.



  • Ja das meinte ich eigentlich auch, dass der Operator >> überladen wird, das Prinzip kenn ich, hab es aber tatsächlich nur 1x (in Python) genutzt. 😉
    Und in deinem Beispiel wollte ich nur sicher gehen, dass ich das richtig gecheckt hab. 😃

    Jedenfalls Danke, hab mich jetzt erst mal mit einem Minimal-Beispiel mit nur einer einfachen Zahleingabe und Zahlenliste eingefuchst. 🙂

    Danke!

    AlphaX2



  • So ich hab nochmal probiert und das ganze soweit (dachte ich), auf die Reihe bekommen, hab nun aber ein Problem mit der Ausgabe, der Code sieht jetzt so aus:

    #include <iostream>
    #include <string>
    #include <vector>
    
    struct Person
    {
        std::string name;
        std::string surname;
        float hours;
    };
    
    struct Person add_person()
    {
        Person p;
        std::cout << "Vorname: ";
        std::cin >> p.name;
    
        std::cout << "Nachname: ";
        std::cin >> p.surname;
    
        std::cout << "Stunden: ";
        std::cin >> p.hours;
    
        return p;
    }
    
    int main()
    {
        std::vector<Person> personenliste;
        Person result;
    
        do
        {
            result = add_person();
            personenliste.push_back(result);
        } while(personenliste.size() < 3);
    
        std::cout << "Dies sind die Eingaben:" << std::endl;
        int i;
        for(i=0; i<personenliste.size(); i++)
            std::cout << personenliste[i].name << std::endl;
            std::cout << personenliste[i].surname << std::endl;
            std::cout << personenliste[i].hours << std::endl;
    
        return 0;
    }
    

    Das ganze endet jedoch mit der Ausgabe der Vornamen (alle hintereinander) und anschließend mit einem Speicherzugriffsfehler. 🙄

    Leider bin ich nämlich aus der Beispiel-Ausgabe von SeppJ nicht ganz schlau geworden, also genau genommen wie die for-Schleife hier genutzt wird:

    std::cout << "Folgende Personen sind bekannt:\n";
      for (auto person : personenliste)
        std::cout << person << '\n';
    

    Vielen Dank für jeden weiteren Tipp. 😉

    AlphaX2



  • AlphaX2 schrieb:

    ...
        int i;
        for(i=0; i<personenliste.size(); i++)
            std::cout << personenliste[i].name << std::endl;
            std::cout << personenliste[i].surname << std::endl;
            std::cout << personenliste[i].hours << std::endl;
    ...
    

    Auf Anhieb fallen mir diese Zeilen schon auf.

    1. solltest du (sofern es nicht einen guten Grund gibt) die Deklaration von i auch in der Schleife machen... Dann sollte dir der 2te Fehler schon selbst auffallen.

    2. Einrückung macht noch keinen Scope. Überlege mal wozu die geschweiften Klammern auch bei Schleifen dienen.



  • * zuviel verraten *



  • AlphaX2 schrieb:

    Leider bin ich nämlich aus der Beispiel-Ausgabe von SeppJ nicht ganz schlau geworden, also genau genommen wie die for-Schleife hier genutzt wird:

    std::cout << "Folgende Personen sind bekannt:\n";
      for (auto person : personenliste)
        std::cout << person << '\n';
    

    Diese for-Schleife (ebenso wie 'auto') funktioniert nur mit C++11, und ist eine spezielle Form (In anderen Sprachen wird sie häufig foreach genannt). Der erste Ausdruck ist das Element, der zweite die Liste über die iteriert wird.



  • Okay wo ist der Facepalm Smilie 😃
    Danke! Jetzt geht es wunderbar! 🙂

    Ah okay, werd ich mal paar Infos einholen zu dem for mit auto, klingt so, als würde es ähnlich wie in Python funktionieren.

    Mal noch eine allgemeine Frage, bei dem Tutorial auf learncpp.com wird immer ein using namespace std; genutzt, hier scheint es ja die Mehrheit zu lassen und immer das std:: mit zu schreiben. Woran soll(te) man sich denn halten?

    Vielen Dank.



  • AlphaX2 schrieb:

    Ah okay, werd ich mal paar Infos einholen zu dem for mit auto, klingt so, als würde es ähnlich wie in Python funktionieren.

    Das auto hat erst einmal nichts mit diesem Schleifentyp zu tun. auto ist ein Stellvertreter für einen Typ der sich eindeutig herleiten lässt. Dient im wesentlichen der verkürzten Schreibweise:

    // Was findest du verständlicher:
    std::vector<int> intvector;
    //...
    // Alte Schleifenvariante und Iteratorverwendung ohne auto
    for(std::vector<int>::const_iterator it=intvector.begin(), end=intvector.end(); it!=end; ++it)
        cout << *it;
    
    // Alte Schleifenvariante und Iteratorverwendung mit auto
    for(auto it=intvector.begin(), end=intvector.end(); it!=end; ++it)
        cout << *it;
    

    Nachtrag:
    Die neue for-Schleife ("for each"), hat den Aufbau: "for(<Typ> <Variablenname> : <Container>)" - du bist nicht gezwungen in dieser Kombination auto zu verwenden. Aber es bietet sich hier fast an.

    AlphaX2 schrieb:

    Mal noch eine allgemeine Frage, bei dem Tutorial auf learncpp.com wird immer ein using namespace std; genutzt, hier scheint es ja die Mehrheit zu lassen und immer das std:: mit zu schreiben. Woran soll(te) man sich denn halten?

    Solange du niemals using namespace im Header, und immer hinter allen Inkludes machst, wird dir kaum einer reinreden, dann sind es persönliche Stilvorlieben. Erst wenn es zu Namenskonflikten kommt wird man dann etwas vorsichtiger.



  • AlphaX2 schrieb:

    Mal noch eine allgemeine Frage, bei dem Tutorial auf learncpp.com wird immer ein using namespace std; genutzt, hier scheint es ja die Mehrheit zu lassen und immer das std:: mit zu schreiben. Woran soll(te) man sich denn halten?

    Witzig, die Frage wiederholt sich ja.

    http://www.c-plusplus.net/forum/p2232284#2232284

    So, jetzt haben wir den Thread zweimal 😉

    Achja, das mit for(auto a : b) ist ein range-based for. Der Begriff wurde glaub ich noch nicht genannt. Einfach mal googeln.


Anmelden zum Antworten