Structs, Vektoren, Funktionen.



  • Hi, Leute

    unser Informatik Prof. hat uns eine Übung gestellt. In der wir ein enum mit mehreren Studiengängen erstellen sollten und dann noch ein Struct das vom User Informationen zum Student enthält, Matrikelnummer, Alter, Name, Vorname, Studiengang.

    Also hab ich ein 0 Felder großen vector vom Struct Studenten erstellt, das Ding ist wenn ich den Vector mit push.back erweitern will macht er es einfach nicht 😡 stattdessen gibt er mir aus die Funktion überhaupt nicht bekannt sei und kompiliert als Konsequenz nicht.

    Und ich kann den Studiengang auch nicht einlesen. Da krieg ich auch eine Fehlermeldung die für mich total Kryptisch ist, hier ist die Fehlermeldung:

    main.cpp:86:29: error: no match for ‘operator>>’ in ‘std::cin >> studenten.std::vector<_Tp, _Alloc>::operator[] [with _Tp = student, _Alloc = std::allocator<student>, std::vector<_Tp, _Alloc>::reference = student&, std::vector::size_type = unsigned int](((unsigned int)i))->student::studi’

    Als IDE benutz ich Netbeans.

    Der C++ Code:

    #include <iostream>
    #include <vector>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    //Eigene Datentypen
    
    enum studiengang {
        Bachelor = 1, Master = 2, Kosi = 3, JIM = 4
    };
    
    struct student {
        string nachname;
        string vorname;
        string martrikelNR;
        int alter;
        studiengang studi;
    };
    
    //Ausgabe Funktion
    
    void ausgabeSTUDENT(vector<student> studenten, int SIZE) {
        cout << "Eine Tabellarische ausgabe aller Studenten:\n";
        for (int i = 0; i < SIZE; i++) {
            cout << "Studentenname: " << studenten[i].nachname << ", "
                    << studenten[i].vorname << endl;
            cout << "Matrikelnummer: " << studenten[i].martrikelNR << endl;
    
            cout << "Studiengang: "<< studenten[i].studi << endl;
            cout << "Alter: " << studenten[i].alter << endl;
        }
    }//Funktion wird beendet programm wird terminiert
    
    //MAIN FUNKTION + Einlesen
    
    int main() {
        vector<student> studenten;
        bool eingabe = true;
    
        cout << "Herzlich Willkommen bei der Studi klarmach exe";
        //Eingabe schleifen start
        while (eingabe) {
            static int i = 0; //Vectorzähler
            char beenden;
    
            studenten.push_back(0);
            cout << "Bitte geben sie den Nachnamen des Studenten ein:\n";
            cin >> studenten[i].nachname;
            cout << "\nBitte geben sie den Vornamen des Studenten ein:\n";
            cin >> studenten[i].vorname;
            cout << "\nBitte geben sie das Alter des Studenten ein:\n";
            cin >> studenten[i].alter;
            cout << "\nBitte geben sie die Martrikelnummer des Studenten ein:\n";
            cin >> studenten[i].martrikelNR;
            cout << "\nBitte geben sie den Studiengang des Studenten\n"
                    << "an.(Bachelor=1/Master=1/Kosi=3/JIM=4)\n";
            cin >> studenten[i].studi;
            i++;
    
            cout << "Wollen sie einen weiteren Studenten eingeben n/j.\n";
            cin >> beenden;
    
            if (beenden == ('n' || 'N'))
                eingabe = 1;
            else {
                eingabe = 0;
                ausgabeSTUDENT(studenten, i);
            }
        };
    
    }
    


  • UnterKind schrieb:

    studenten.push_back(0);
    

    0 ist ein Integer, kein Student. Du musst einen Studenten hinzufügen.
    Dreh doch einfach die Reihenfolge um.
    Du erzeugst eine temporäre Variable student.
    Die lässt du dann einlesen und fügst die zum Schluss hinzu.
    Deinen Vectorzähler brauchst du dann auch nicht mehr.
    Für soetwas static Variablen zu verwenden ist auch nicht besonders toll.
    Btw: Hattet ihr schon Iteratoren?



  • studenten.push_back(student)?

    Ich hab static i für den Fall eingebaut das ich da drum rum noch ein menü bastel das in ner while schleife ist die das Programm terminieren kann. Der gedanke ist das wenn ich nach meiner ersten Eingabe nochmal welche eingeben will ich nicht die schon eingegebenen Überschreibe,

    nein ich hab keine Ahnung was Iteratoren sind.

    Ich verstehe den Schritt mit der Temporären Variable Student nicht. Wäre cool wenn du den mir erläutern könntest.



  • Anstatt deine Variable global zu machen, was zu vielen merkwürdigen Fehlern führen kann, deklarier' sie doch einfach einen Scope globaler:

    while (eingabe) {
            static int i = 0; //Vectorzähler
            // [...]
    

    ➡

    for ( int i = 0; eingabe; ) {
            // [...]
    


  • UnterKind schrieb:

    Ich verstehe den Schritt mit der Temporären Variable Student nicht. Wäre cool wenn du den mir erläutern könntest.

    UnterKind schrieb:

    Und ich kann den Studiengang auch nicht einlesen. Da krieg ich auch eine Fehlermeldung[...]

    Ich hab mal versucht beides in einem Beispiel zu verwursten.
    Das enum setzen ist etwas hakelig - das geht auch schöner - aber erstmal reicht's.

    struct gadget{ std::string name; int no; enum category { gizmo, widget} cat; };
    
    void f(){
        std::vector<gadget> gadgets;
        bool weiter = true;
    	while(weiter){
    		gadget tmp;  // temporaere Variable, in die eingelesen wird
    		std::cin >> tmp.name;
    		std::cin >> tmp.no;
    		int cat;  // temporaere Kategorie
    		std::cin >> cat;
    		switch(cat){
    		// standarmäßig gizmo:
    		  default:
    			tmp.cat = gadget::gizmo;
    			break;
    		  case gadget::gizmo:
    		  case gadget::widget:
    			tmp.cat = static_cast<gadget::category>(cat);
    		}
    		gadgets.push_back(tmp);  // speichern
    		weiter = ...;
    	}
    }
    

    Ich habe ausserdem dass Gefühl, dass Du vector<> noch ein wenig vertiefen solltest.
    Das ist nicht nur ein Ersatz für die typischen Arrays, die Dir in Quadrillionen schlechten Tutorials erklärt werden, sondern viel mehr.
    So führt ein vector<> z.B. immer Buch über seine Elemente(Anfang, Ende, Anzahl usw. usf.) Dein i und der SIZE Parameter sind überflüssig.



  • Hey, kam erst jetzt wieder dazu muss mich mal wieder mit dieser Aufgabe ausseinander zu setzen.

    Ich hab ein paar kleine Veränderungen gemacht nix gravierendes.

    Der kram mit dem Vektor funktioniert jetzt easy peasy, hab es über eine Hilfsvariable gemacht. Den Static int zähler hab ich dringelassen. Mein Problem ist aber im Moment das ich bei einer Eingabe einen diesen Fehler hier kriege:

    error: no match for ‘operator>>’ in ‘std::cin >> hilfsvariable’

    mit Hilfsvariable will ich dem enum im Struct einen Wert zuweisen. aber die Eingabe scheitert schon im ersten schritt. Der Fehler steckt laut compiler in Zeile 87 beim cin >> xy; aber ich seh nicht was ich da falsch gemacht haben soll

    Wäre für einen Hinweis sehr dankbar 🙂

    /* 
     * File:   main.cpp
     * Author: Käse ist Lecker
     *
     * Created on 18. April 2013, 16:52
     * 
     * Zweck: Üben mit Structs/Vektoren/Enum, 
     * Aufgabenstellung:
     * Studenten mit Namen, Vornamen, Alter, MatrikelNr, Studiengang(enum)
     * einlesen lass abfrage mit n/j beenden lassen. Ausgabe alle JIM||Kosi&&M.
     * Erweitert: Nutzer entscheiden lassen was ausgegeben wird.
     * 
     * PseudoCode:
     * Erstellen des Enums(Bachelor, Kosi, Master, Jim)
     * Erstellen des Structs Student
     *      Name, Vorname
     *      Alter
     *      MartrikelNr,
     *      Studiengang
     * 
     * Eingabeaufforderung
     *      Schleife
     *              Eingabe des Studenten
     *              Schleife wiederholen(abfragen)
     * 
     * Ausgabe(alle im (Jim||Kosi)&&Nachname M)
     */
    
    #include <iostream>
    #include <vector>
    #include <string>
    #include <iomanip>
    using namespace std;
    
    //Eigene Datentypen
    
    enum studiengang {
        Bachelor = 1, Master = 2, Kosi = 3, JIM = 4
    };
    
    struct student {
        string nachname;
        string vorname;
        string martrikelNR;
        int alter;
        studiengang studi;
    };
    
    //Ausgabe Funktion
    
    void ausgabeSTUDENT(vector<student> studenten, int SIZE) {
        cout << "Eine Tabellarische ausgabe aller Studenten:\n";
        for (int i = 0; i < SIZE; i++) {
            cout << "Studentenname: " << studenten[i].nachname << ", "
                    << studenten[i].vorname << endl;
            cout << "Matrikelnummer: " << studenten[i].martrikelNR << endl;
    
            cout << "Studiengang: " << studenten[i].studi << endl;
            cout << "Alter: " << studenten[i].alter << endl;
        }
    }//Funktion wird beendet programm wird terminiert
    
    //MAIN FUNKTION + Einlesen
    
    int main() {
        vector<student> studenten;
        student vektorEINGABE; //temporäre Variable zum Einspeichern in den Vektor
        bool eingabe = true;
        studiengang hilfsvariable;
    
        cout << "Herzlich Willkommen bei der Studi klarmach exe";
        //Eingabe schleifen start
        while (eingabe) {
            static int i = 0; //Vectorzähler
            char beenden;
    
            cout << "Bitte geben sie den Nachnamen des Studenten ein:\n";
            cin >> vektorEINGABE.nachname;
            cout << "\nBitte geben sie den Vornamen des Studenten ein:\n";
            cin >> vektorEINGABE.vorname;
            cout << "\nBitte geben sie das Alter des Studenten ein:\n";
            cin >> vektorEINGABE.alter;
            cout << "\nBitte geben sie die Martrikelnummer des Studenten ein:\n";
            cin >> vektorEINGABE.martrikelNR;
            cout << "\nBitte geben sie den Studiengang des Studenten\n"
                    << "an.(Bachelor=1/Master=1/Kosi=3/JIM=4)\n";
            cin >> hilfsvariable;
            vektorEINGABE.studi = hilfsvariable;
    
            studenten.push_back(vektorEINGABE);
    
            i++;
    
            cout << "Wollen sie einen weiteren Studenten eingeben n/j.\n";
            cin >> beenden;
    
            if (beenden == 'n' || beenden == 'N')
                eingabe = 0;
            else {
                eingabe = 1;
                ausgabeSTUDENT(studenten, i);
            }
        };
    
    }
    

  • Mod

    Auch wenn ein enum manchmal so aussieht, als wäre es ein int, so ist es doch für das Typensystem keiner. Für das Typensystem ist es ein eigener Typ (und das ist auch gut so! In C++11 kann man das sogar nochmal strenger handhaben lassen). Für dein enum studiengang hast du keinen passenden Einleseoperator definiert.

    Mach deine Hilfsvariable mal vom Typ int. Dann gibst du durch eine Fallunterscheidung deinem enum-Member passende Werte. Das kannst und solltest du noch in einem Leseoperator wegkapseln, damit der Code übersichtlich bleibt und du es nur einmal schreiben brauchst. Ebenso könnte dein struct student einen solchen Operator gut gebrauchen.

    Noch eine Stilbemerkung: In C++ ist es üblich, Variablen wirklich erst dort zu definieren, wo sie gebraucht werden, anstatt am Anfang des Scopes.



  • Hab hilfsvariable nun als int definiert trotzdem macht kriege jetzt diese fehlermeldung

    main.cpp:88:31: error: invalid conversion from ‘int’ to ‘studiengang’

    Ich versteh nicht ganz was du mit dem Leseoperator meinst. Wäre nett wenn du mir das näher bringen könntest.


  • Mod

    UnterKind schrieb:

    Hab hilfsvariable nun als int definiert trotzdem macht kriege jetzt diese fehlermeldung

    main.cpp:88:31: error: invalid conversion from ‘int’ to ‘studiengang’

    Du sollst ja auch nicht bloß die Hälfte des Ratschlags umsetzen. Klar, dass das nicht funktioniert.

    SeppJ schrieb:

    Mach deine Hilfsvariable mal vom Typ int. Dann gibst du durch eine Fallunterscheidung deinem enum-Member passende Werte.

    Ich versteh nicht ganz was du mit dem Leseoperator meinst. Wäre nett wenn du mir das näher bringen könntest.

    Das kann ich bei deinem Kenntnisstand nicht im Rahmen des Forums, außer durch den zweiten und vierten Link in meiner Signatur.


Anmelden zum Antworten