Schuelerdatenverwaltung mit Menu (OOP)



  • Kann mir jemand für dieses Projekt einen Input oder einen Denkanstoß, wie ich hinbekommen könnte, dass ich per switch case Anweisung 1) Schueler anlegen kann und die Daten sollen dann verfügbar bleiben um sie jederzeit, auch wenn man z.B. Menupunkt 3)Schueler einzeln suchen und anzeigen aufgerufen hat, mit dem druecken der Taste 2 die Daten sich anzeigen lassen kann. Wäre dankbar für ein kleines Beispiel als Hilfe. Meine Vermutung ist, es könnte mit den Methoden mit/ ohne Rückgabewert oder auch den Übergabeparametern funktionieren.

    Aufgabenstellung
    Projekt schueler zur Übung der OOP

    Erstelle ein Projekt schueler zur Verwaltung von Schülerdaten.

    Deklariere dazu eine Klasse schueler mit folgenden Datenfeldern:

    • s_nr
    • s_name
    • s_vname
    • s_wohnort

    Das Programm soll in Form einer Menuauswahl folgendes leisten:

    • Schueler anlegen
    • Schuelerdaten anzeigen
    • Schueler einzeln suchen und anzeigen
    • Schuelerdaten bearbeiten (vorerst nur den Wohnort)

    Hier mein bisheriger Code:

    // projekt_schueler.cpp : Diese Datei enthält die Funktion "main". Hier beginnt und endet die Ausführung des Programms.
    //

    #include <iostream>
    #include <string>
    using namespace std;
    
    
    class schueler {
    private:
    	int s_nr;
    	string s_name;
    	string s_vname;
    	string s_wohnort;
    public:
    	schueler(int, string, string, string);
    	schueler();
    	int getNummer(void);
    	string getName(void);
    	string getVname(void);
    	string getWohnort(void);
    	//Methoden
    	void zurueck(void);
    
    
    
    
    };
    
    
    schueler::schueler(int N, string name, string vname, string wohnort)
    {
    	s_nr = N;
    	s_name = name;
    	s_vname = vname;
    	s_wohnort = wohnort;
    }
    schueler::schueler(void)
    {
    	s_nr = 0;
    	s_name = "NN";
    	s_vname = "NN";
    	s_wohnort = "NN";
    }
    int schueler::getNummer(void)
    {
    	return s_nr;
    }
    string schueler::getName(void)
    {
    	return s_name;
    }
    string schueler::getVname(void)
    {
    	return s_vname;
    }
    string schueler::getWohnort(void)
    {
    	return s_wohnort;
    }
    void schueler::zurueck(void)
    {
    
    }
    int main()
    {
    	char auswahl = 'NN';
    	int nummer = 0;
    	string name = "NN";
    	string vname = "NN";
    	string wohnort = "NN";
    	string auswahlkrite;
    	int i = 0;
    	int anzahl = 0;
    	int choice = 0;
    	int s_nummer = 0;
    
    
    
    	cout << "==============HAUPTMENU=================" << endl;
    	cout << "Schueler anlegen                     ==> 1" << endl;
    	cout << "Schuelerdaten anzeigen               ==> 2" << endl;
    	cout << "Schueler einzeln suchen und anzeigen ==> 3" << endl;
    	cout << "Schuelerdaten bearbeiten             ==> 4" << endl;
    	cout << "Speicherplatz freigeben               ==> 5" << endl;
    	cout << "Bitte geben Sie ihre gewuenschte Aktion ein:";
    	cin >> choice;
    	schueler* schuel[10];
    	
    
    
    	
    		do {
    			cout << "Schueler anlegen:" << endl;
    			cout << "Schuelernummer:";
    			cin >> nummer;
    			if (nummer != 'XX')
    			{
    				cout << "Name:";
    				cin >> name;
    				cout << "Vorname:";
    				cin >> vname;
    				cout << "Wohnort:";
    				cin >> wohnort;
    				schuel[i] = new schueler(nummer, name, vname, wohnort);
    
    				
    				system("cls");
    			}
    			i++;
    		} while (nummer != 'XX');
    		anzahl = i;
    	
    		cout << "==============HAUPTMENU=================" << endl;
    		cout << "Schueler anlegen                     ==> 1" << endl;
    		cout << "Schuelerdaten anzeigen               ==> 2" << endl;
    		cout << "Schueler einzeln suchen und anzeigen ==> 3" << endl;
    		cout << "Schuelerdaten bearbeiten             ==> 4" << endl;
    		cout << "Speicherplatz freigeben               ==> 5" << endl;
    		cout << "Bitte geben Sie ihre gewuenschte Aktion ein:";
    		cin >> choice;*/
    
    
    
    
    		//Ausgabe
    		for (i = 0; i < anzahl; i++)
    		{
    			cout << "___________________________________________" << endl;
    			cout << "Nummer :" << schuel[i]->getNummer() << endl;
    			cout << "Name   :" << schuel[i]->getName() << endl;
    			cout << "Vorname:" << schuel[i]->getVname() << endl;
    			cout << "Wohnort:" << schuel[i]->getWohnort() << endl;
    			cout << "____________________________________________" << endl;
    		}
    	
    
    
    	
    		cout << "Nach welcher Schuelernummer suchen Sie?";
    		cin >> s_nummer;
    			
    /*hier sollte eigentlich die if-Abfrage nach der Schuelernummer kommen,
    ob diese im Array vorhanden ist oder nicht, hatte aber mit dem Array schuel[i] Probleme: ich habe die Werte für das Array schuel[i] dann im Mnenupunkt 1 schon initialisiert, jedoch habe ich dann keinen Zugriff mehr auf die Werte in den anderen Menupunkten. Kann mir jemand dabei helfen??*/
    
    
    
    				for (i = 0; i < anzahl; i++)
    				{
    					cout << "___________________________________________" << endl;
    					cout << "Nummer :" << schuel[i]->getNummer() << endl;
    					cout << "Name   :" << schuel[i]->getName() << endl;
    					cout << "Vorname:" << schuel[i]->getVname() << endl;
    					cout << "Wohnort:" << schuel[i]->getWohnort() << endl;
    					cout << "____________________________________________" << endl;
    				}
    			
    
    
    
    
    
    
    
    
    
    
    
    
    	//Speicherplatzfreigabe
    
    	for (i = 0; i < anzahl; i++)
    	{
    		delete schuel[i];
    	}
    
    	system("pause");
    	return 0;
    
    }
    	
    		
    /*Ich bedanke mich ganz herzlich im Voraus schon bei allen Helfenden :)
    Einen schönen Abend wünsche ich.
    
    Viele Grüße Morten*/

  • Mod

    @Morten31 sagte in Schuelerdatenverwaltung mit Menu (OOP):

    schueler* schuel[10];

    Du machst damit so ziemlich alles falsch damit, was man falsch machen kann. Aber es gibt eine gute Nachricht: Vergiss Zeiger, Arrays, new, etc.! Du machst schließlich C++. Brauchst du alles nicht. In C++ gibt es viele fertige Containerklassen, und die können die Speicherverwaltung richtig. std::string ist eine davon, und die benutzt du ja auch schon und kämst (hoffentlich) niemals auf die Idee, selber mit rohen char-Arrays herumzumachen.

    Hier hast du eine Menge oder eine Liste von Schülern. Passende Container für diesen Zweck könnten std::vector oder std::set sein. Vector ist eher das Konzept einer geordneten Liste von Einträgen, aber Einträge können auch mehrfach vorkommen. Set ist eher das Konzept einer mathematischen Menge, jedes Element darin ist einmalig und eindeutig. Vector ist für dich wahrscheinlich einfacher zu nutzen, weil es eher deinem vormaligen Array entspricht. Set ist passender und macht die anderen Aufgabenteile einfacher.

    Für das Set musst du noch einen Ordnungsoperator für deine Klasse definieren (oder einen beim Erstellen des Sets angeben). Dieser wird dazu genutzt, um die Eindeutigkeit der Elemente sicher zu stellen, und um diese später wieder zu finden. Bei dir wäre das wohl die s_nr. Da merkt man dann auch, wieso das set wahrscheinlich passender ist: Bei der Aufgabe, die Daten zu bearbeiten, würdest du anstatt irgendwie selber in der Menge nach dem Eintrag mit der passenden s_nr zu suchen, stattdessen einfach das Set fragen, dass es dir den passenden Eintrag gibt. Und das macht das Set dann auch richtig und du kannst nix mehr falsch machen dabei.

    PS: Die von mir verlinkte Seite ist wahrscheinlich etwas überwältigend, wenn man sie das erste Mal sieht. Euer Lehrer hat offensichtlich auch versagt und bringt euch diese Grundlagen nicht bei. Hast du ein Buch? In guten Anfängerbüchern sollte wenigstens Vector anfängerfreundlich erklärt werden. Und wenn man Vector kann, dann versteht man auch die verlinkte Anleitung zum Set.



  • @SeppJ Danke für die Hilfe😀👍 . Werde mich da morgen dran setzen und das Ganze ausprobieren.



  • Schreibe bitte in Zukunft in eine Zeile vor Deinem Code ``` und in eine Zeile nach Deinem Code ```. Alternativ markiere Deinen Code und klicke auf das </> in der Symbolleiste über dem Eingabefeld.
    Du kannst Deine Beiträge auch im Nachhinein bearbeiten. Den Menüpunkt "Bearbeiten" findest Du in dem Drei-Punkte-Menü rechts unter Deinen Beiträgen.
    Danke.



  • @Morten31 sagte in Schuelerdatenverwaltung mit Menu (OOP):

    Kann mir jemand für dieses Projekt einen Input oder einen Denkanstoß, wie ich hinbekommen könnte, dass ich per switch case Anweisung ...

    Bitte sehr:

    #include <iostream>
    #include <string>
    #include <vector>
    
    class Student {
    public:
    	Student(int nr) : nr_(nr) { }
    	void set_name(const std::string& name) { }
    	void add_name(const std::string& name) { }
    	void set_family_name(const std::string& name) { }
    	void set_residence(const std::string& residence) { }
    
    	friend std::ostream& operator<<(std::ostream& os, const Student& student) {
    		// hier gibst Du die Daten von student aus...
    		return os;
    	} // Schuelerdaten anzeigen
    
    private:
    	int nr_;
    	std::vector<std::string> names_;
    	std::string family_name_;
    	std::string residence_;
    };
    
    
    class School {
    public:
    	School(std::string name, int nr = 0) : nr_(nr), name_(name) { }
    	void add_student(int nr) { } // Schueler anlegen
    	Student& get_student(int nr) { } // Schueler einzeln suchen und anzeigen
    	void update_student(Student student) { } // Schuelerdaten bearbeiten (vorerst nur den Wohnort)
    	int student_count() { return students_.size(); }
    	friend std::ostream& operator<<(std::ostream& os, const School& school) {
    		// hier gibst Du die Daten von school aus...
    		return os;
    	} // Schooldaten anzeigen
    
    
    private:
    	int nr_;
    	std::string name_;
    	std::vector<Student> students_;
    };
    
    int main_choice() {
    	int choice = 0;
    
    	std::cout << "==============HAUPTMENU=================\n";
    	std::cout << "[1]\tSchueler anlegen\n";
    	std::cout << "[2]\tSchuelerdaten anzeigen\n";
    	std::cout << "[3]\tSchueler einzeln suchen und anzeigen\n";
    	std::cout << "[4]\tSchuelerdaten bearbeiten\n";
    	std::cout << "[0]\tProgramm beenden\n\n";
    	std::cout << "Bitte geben Sie ihre gewuenschte Aktion ein: ";
    	std::cin >> choice;
    
    	return choice;
    }
    
    int main() {
    	School schule("OldSchool", 42);
    
    	while(int c = main_choice()) { // alles was keine Zahl oder 0 ist, führt zum Abbruch
    		switch(c) {
    			case 1:
    				// eine Funktion um den Schueler anzulegen, z.b.:
    				// schule.add_student(schule.student_count()+1);
    				break;
    			default:
    				break;
    		}
    	}
    	return 0;
    }
    

    Da hast Du noch einiges zu tun. Viel Spass!



  • @Swordfish Danke für den Hinweis.Habe ich eben gemacht👍



  • @daMicha
    Gibt´s nen Grund dafür, warum du fast alle Methoden virtual deklarierst? Und wozu dient Student::add_name()?

    Was passiert, denn bei get_student() eine unbenutzte ID übergeben wird? Ich würde das eher als Student const* find_student( int id ) const implementieren und ggf. nullptr zurückgeben. Da der Eintrag nur über "Bearbeiten" verändert werden darf ist der Rückgabewert ein Zeiger auf ein konstantes Objekt. Bei update_student() würde ich den Parameter ebenfalls const machen und anhand der ID den Eintrag aus der Datenbasis aktualisieren:

    public :
       Student const* School::find_student( int id ) const
       {
          // die non-const Methode benutzen. Ist für diese Funktion zwar Overkill, aber zeigt, wie man 
          // die non-const Methode wiederbenutzen kann. 
          return const_cast<Student const*>( const_cast<School*>( this )->internal_find_student( id ) );
       }
    
    private:
       Student* School::internal_find_student( int id ) 
       {
          ...
       }
    
       bool School::update_student( Student const& student )
       {
          Student* existing = internal_find_student( student.id() );
          if( existing )
          {
             // existing zeigt auf den "echten" Eintrag in der Datenbasis, Attribute aus dem übergebenem Parameter übernehmen
          }
          // der Zeiger kann implizit zu bool konvertiert werden. Wenn der Eintrag gefunden wurde ist er geändert worden
          return existing;
       }
    


  • @daMicha Vielen Dank für den Input!😀



  • @DocShoe sagte in Schuelerdatenverwaltung mit Menu (OOP):

    @daMicha
    Gibt´s nen Grund dafür, warum du fast alle Methoden virtual deklarierst?

    Habs rausgenommen. Danke.

    Und wozu dient Student::add_name()?

    für: Klaus Maria Otto Hoffmanshausen

    Deine restlichen Anregungen sind sicher auch ein toller Input für den OP. (und mich)

    So könnte man die class School die Nummern-Verwaltung machen lassen und bei einem find:student(name) nur diese Nummer zurückgeben oder 0.



  • @daMicha Ich gebe euch dann gerne Feedback wenn das Programm funktioniert👍


Log in to reply