Schulnotenprogramm in C++



  • So! Will mal ein Schulnotenprogramm in C++ schreiben. Aber wie soll ich das jetzt anstellen?! Will das sich eine normal Konsole öffnet und man dann Fächer und Schüler anlegen kann.... Die Noten sollen in einer Externen Datei gespeichert werden und bei neustart des Programms wieder mit aufgerufen werden so das ich nicht immer alle Noten neu eingeben muss. Aber was muss jetzt alles in den Quelltext. Hab bis jetzt keine Ahnung..., denn ich habe immer nur kleine Programm ohne einlesen einer externen Datei geschrieben...!

    Würde mich über Antworten freuen.

    Gruß Angel



  • Dann solltest du dir vorher doch nochmal fsream anschauen. Ein Projekt in dieser Art lohnt sich erst, wenn man die Grundlagen kennt.



  • mach doch mal ne switch für das menü

    und für jedes case eine eigene funktion

    oder über ein Klasse



  • und schreib/mal dir am besten auf einem zettel auf was das dein programm alles können muss.
    dann noch die reihenfolge in der es ablaufen muss.

    und dann fängst du eben an jeden einzelnen teil zu schreiben.
    und ggf. fragen hier zu stellen.
    die gesamtaufgabe ist an dieser stelle noch relativ unwichtig.



  • Na prinzipiell würde ich um die Daten einzutragen über ein mehrdimensionales Array gehen und in eine Datei schreiben kannste ja mit den Funktionen
    fopen(), fwrite() und fclose()



  • bevor du ein mehrdimensionales array wählst, ist ein struktur-array wohl besser geeignet. zum beispiel:

    struct Schueler
    {
    string Name;
    int Mathe[y];      /* in diesem Array speicherst du die Mathe-Noten des
    einzelnen Schuelers, y steht für die Anzahl der Noten*/
    int Deutsch[y];
    ...
    ...
    ...
    };
    Schueler Noten[x];   /* dieses Array verwaltet die einzelnen Schueler, 
    mitsamt Noten, Name, etc. was immer du willst. x steht für die Anzahl der
    Schüler, wenn du nur einen Schüler verwalten willst, z.B. dich, dann mach kein
    Array, sondern nur ne normale Variable.*/
    

    zum thema struktur findest du bestimmt einen artikel hier im forum oder woanders im internet. ist eigentlich total einfach, der vorteil gegenüber einem mehrdim. array liegt darin, dass du hier verschiedene datentypen verwalten kannst, in einem mehrdim. array müssen alle daten vom gleichen typ sein.

    ich hoffe, dir einen kleinen ansatz gegeben zu haben.
    ansonsten, wie die anderen schon sagen, mach erstmal ein nummern-geführtes menu. per zahleneingabe wählst du dann, was du machen willst.

    ich weiß net, wie gut deine kenntnisse sind, aber mit ext. dateien zu arbeiten hat es ziemlich in sich. hast du dich schonmal mit zeigern beschäftigt?



  • Hab jetzt mal was geschrieben..., aber es treten leider Linker fehler auf...! Was ist falsch?

    #include <iostream>		//standart :?
    #include <string>		//die strings 
    #include <fstream>		//laden speichern
    #include "klassen.h"	//alle meine klassen
    
    using namespace std;	//standart :?
    
    void pau()	//gibt ja kein pause unter unix
    {			//also selber eins machen
    	#ifdef unix
    	cout << "\n Bitte drücken Sie die Enter-Taste!";
    	#else
    	cout << "\n Bitte drcken Sie die Enter-Taste!";
    	#endif
    	cin.get();
    	cin.get();
    }
    
    void cls()
    {
         #ifdef unix //unix-konform
         system("clear");
         #else
         system("cls");
         #endif
    }
    
    void uberschrift(int i) //menüs
    {
    	if(i==1)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  ________________ "
    			 << "\n |Eintrag erfassen|"
    			 << "\n  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ \n";
    		#else
    		cout << "\n  ________________ "
    			 << "\n |Eintrag erfassen|"
    			 << "\n  îîîîîîîîîîîîîîîî \n";
    		#endif
    	}
    	if(i==2)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  ________________ "
    			 << "\n |Eintrag ergänzen|"
    			 << "\n  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ \n";
    		#else
    		cout << "\n  ________________ "
    			 << "\n |Eintrag erg„nzen|"
    			 << "\n  îîîîîîîîîîîîîîîî \n";
    		#endif
    	}
    	if(i==3)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  ________________ "
    			 << "\n |Eintrag anzeigen|"
    			 << "\n  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ \n";
    		#else
    		cout << "\n  ________________ "
    			 << "\n |Eintrag anzeigen|"
    			 << "\n  îîîîîîîîîîîîîîîî \n";
    		#endif
    	}
    	if(i==4)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  _______________ "
    			 << "\n |Eintrag löschen|"
    			 << "\n  ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯ \n";
    		#else
    		cout << "\n  _______________ "
    			 << "\n |Eintrag l™schen|"
    			 << "\n  îîîîîîîîîîîîîîî \n";
    		#endif
    	}
    	if(i==5)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  _______ "
    			 << "\n |Beenden|"
    			 << "\n  ¯¯¯¯¯¯¯ \n";
    		#else
    		cout << "\n  _______ "
    			 << "\n |Beenden|"
    			 << "\n  îîîîîîî \n";
    		#endif
    	}
    	if(i==6)
    	{		
    		cls();
    		#ifdef unix
    		cout << "\n  ____ "
    			 << "\n |Info|"
    			 << "\n  ¯¯¯¯ \n";
    		#else
    		cout << "\n  ____ "
    			 << "\n |Info|"
    			 << "\n  îîîî \n";
    		#endif
    		cout << "\n Programmierung\t\t!!Angel!!";
    
    		}
    	if(i==0)
    	{
    		cls();
    		#ifdef unix
    		cout << "\n  ____ "
    			 << "\n |MENÜ|"
    			 << "\n  ¯¯¯¯ \n";
    		#else
    		cout << "\n  ____ "
    			 << "\n |MENš|"
    			 << "\n  îîîî \n";
    		#endif
    		cout << "\n 1 = Eintrag erfassen";
    
    		#ifdef unix
    		cout << "\n 2 = Eintrag ergänzen";
    		#else
    		cout << "\n 2 = Eintrag erg„nzen";
    		#endif
    
    		cout << "\n 3 = Eintrag ausgeben";
    
    		#ifdef unix
    		cout << "\n 4 = Eintrag löschen";
    		#else
    		cout << "\n 4 = Eintrag l™schen";
    		#endif
    
    		cout << "\n 5 = Beenden\n"
    			 << "\n i = Infos\n\n ";
    	}
    }
    
    int main()
    {
    	// Init's
    	char janein, ein1;
    	int ende=1;
    	Schueler schueler;
    	Fach fach;
    	Note noten;
    	// Ende Init's
    
    	///////////////
    	// HAUPTMENÜ //
    	///////////////
    	while(ende==1)
    	{
    		uberschrift(0);
    		cin >> ein1;
    
    		////////////////////////
    		// Untermenü ERFASSEN //
    		////////////////////////
    		if(ein1=='1')
    		{
    			uberschrift(1);
    
    			#ifdef unix
    			cout << "\n Name Schüler: ";
    			#else
    			cout << "\n Name Schler: ";
    			#endif
    
    			cin >> schueler.NAME;
    			cout << "\n Fach: ";
    			cin >> fach.NAME;
    			cout << "\n Note: ";
    			cin >> noten.WERT;
    
    			schueler.anlegen(schueler.NAME,fach.NAME,noten.WERT);
    		}
    
    		////////////////////////
    		// Untermenü ERGÄNZEN //
    		////////////////////////
    		if(ein1=='2')
    		{
    			uberschrift(2);
    
    			schueler.ist_da();
    
    			#ifdef unix
    			cout << "\n Name Schüler: ";
    			#else
    			cout << "\n Name Schler: ";
    			#endif
    
    			cin >> schueler.NAME;
    
    			uberschrift(2);
    
    			fach.ist_da(schueler.NAME);
    
    			cout << "\n Fach: ";
    			cin >> fach.NAME;
    
    			uberschrift(2);
    
    			#ifdef unix
    			cout << "\n Note für " << schueler.NAME << " im Fach " << fach.NAME << ": ";
    			#else
    			cout << "\n Note fr " << schueler.NAME << " im Fach " << fach.NAME << ": ";
    			#endif
    
    			cin >> noten.WERT;
    
    			schueler.ergaenzen(schueler.NAME,fach.NAME,noten.WERT);
    		}
    
    		////////////////////////
    		// Untermenü ANZEIGEN //
    		////////////////////////
    		if(ein1=='3')
    		{
    			uberschrift(3);
    
    			schueler.ist_da();
    
    			#ifdef unix
    			cout << "\n Name Schüler: ";
    			#else
    			cout << "\n Name Schler: ";
    			#endif
    
    			cin >> schueler.NAME;
    
    			uberschrift(3);
    
    			fach.ist_da(schueler.NAME);
    
    			cout << "\n Fach: ";
    			cin >> fach.NAME;
    
    			uberschrift(3);
    
    			#ifdef unix
    			cout << "\n Noten für " << schueler.NAME << " im Fach " << fach.NAME << ":\n ";
    			#else
    			cout << "\n Noten fr " << schueler.NAME << " im Fach " << fach.NAME << ":\n ";
    			#endif
    
    			schueler.anzeigen(schueler.NAME, fach.NAME);
    		}
    
    		///////////////////////
    		// Untermenü LÖSCHEN //
    		///////////////////////
    		if(ein1=='4')
    		{
    			uberschrift(4);
    
    			schueler.ist_da();
    
    			#ifdef unix
    			cout << "\n Name Schüler: ";
    			#else
    			cout << "\n Name Schler: ";
    			#endif
    
    			cin >> schueler.NAME;
    
    			uberschrift(4);
    
    			schueler.loeschen(schueler.NAME);
    		}
    
    		///////////////////////
    		// Untermenü BEENDEN //
    		///////////////////////
    		while(ein1=='5')
    		{
    			uberschrift(5);
    
    			cout << "\n Wirklich beenden ? j/n ";
    			cin >> janein;
    			if(janein=='j'){ein1='0';ende=0;}
    			else {if(janein=='n'){ende=1;ein1='0';}}
    		}
    
    		///////////////////////////
    		// Untermenü Information //
    		///////////////////////////
    		if(ein1=='i')
    		{
    			uberschrift(6);
    
    			pau();
    		}
    	}
    	cls();
    	return 0;
    }
    

    dazu noch die devinierten Klassen

    #include <string>
    
    #ifndef KLASSEN_H
    #define KLASSEN_H
    
    struct Datum
    {
    	std::string jahr;
    	std::string monat;
    	std::string tag;
    //	int schaltjahr;
    	int jahr_int;
    	int monat_int;
    	int tag_int;
    
    	bool istGueltig(std::string& DATUM);
    	void wandeln();
    	std::string zusammenbauen(int tag_in2,int monat_in2,int jahr_in2);
    };
    
    struct Schueler
    {
    	std::string NAME;
    
    	float durchschnitt(std::string NAME, std::string FACH);
    	void anzeigen(std::string NAME, std::string FACH);
    	void anlegen(std::string NAME, std::string FACH, std::string NOTE);
    	void ergaenzen(std::string NAME, std::string FACH, std::string NOTE);
    
        void loeschen(std::string NAME);
    	void ist_da();
    };
    
    struct Fach
    {
    	std::string NAME;
    	void ist_da(std::string NAME);
    };
    
    struct Note
    {
    	std::string WERT;
    };
    
    #endif //KLASSEN_H
    

    Hoffe ihr könnt mir helfen die Linker erros zu finden.

    Gruß



  • Hallo,

    Hast du die Memberfunktionen deiner Klassen auch irgendwo definiert? Wenn ja ist diese cpp mit gelinkt?
    Du solltest übrigens deine Strings nicht als Kopie, sondern eher als konstante Referenz übergeben.



  • Du benötigst noch eine "Klassen.cpp", in der du die Methoden deiner Klassen definierst.

    PS: Für die uberschrift()-Funktion könntest du mal über switch-case nachdenken 😉

    PPS: Bei den Klassenmethoden bin ich gerade etwas unsicher, wie die funktionieren sollen.



  • Ups.... Hab ichh ja vergessen zu Posten die Klassen.cpp

    #include <iostream>		//standart :?
    #include <string>		//die strings 
    #include <fstream>		//laden speichern
    #include <sstream>		//_itoa ersatz
    #include "klassen.h"	//alle meine klassen
    
    using namespace std;
    
    void cls();
    void pau();
    
    void Datum::wandeln()	//sichern dass man auch 
    {						//buchstaben eintippen kann
    	jahr_int=atoi(jahr.c_str());
    	monat_int=atoi(monat.c_str());
    	tag_int=atoi(tag.c_str());
    }
    
    string int2ascii(int WERT, string ruckgabe) //der int-zu-ascii
    {											//konverter
    	ostringstream wandler;
    	wandler << WERT;
    	ruckgabe=wandler.str();
    	return ruckgabe;
    }
    
    bool Datum::istGueltig(string& DATUM)	//test ob datum gültig
    {
    	wandeln();
    	DATUM = zusammenbauen(tag_int,monat_int,jahr_int);
    
    	if(jahr_int == 0) return false;
    	if(monat_int > 0 && monat_int < 13)
    	{
    		//if(schaltjahr==1){if(monat == 2)
    		//{if(tag > 0 || tag < 30) return true;}
    		//else{
    		if(monat_int == 2)
    		{if(tag_int > 0 || tag_int < 29) return true;}
    		//}
    
    		if(monat_int == 4
    		|| monat_int == 6
    		|| monat_int == 9
    		|| monat_int == 11)
    		{if(tag_int > 0 || tag_int < 31) return true;}
    
    		if(monat_int == 1 
    		|| monat_int == 3 
    		|| monat_int == 5 
    		|| monat_int == 7 
    		|| monat_int == 8 
    		|| monat_int == 10 
    		|| monat_int == 12)
    		{if(tag_int > 0 || tag_int < 32) return true;}
    	}
    	return false;
    }
    
    string Datum::zusammenbauen(int tag_in2,int monat_in2,int jahr_in2)
    {								//datum zusammenbauen
    	string DATUM;
    
    	// unnötig aber der vollständigkeit halber :
    	if(tag_in2<10){DATUM = "0";DATUM += int2ascii(tag_in2, DATUM);}
    	else{DATUM = int2ascii(tag_in2, DATUM);}
    	DATUM +=".";
    	if(monat_in2<10){DATUM += "0";DATUM += int2ascii(monat_in2, DATUM);}
    	else{DATUM += int2ascii(monat_in2, DATUM);}
    	DATUM +=".";
    	if(jahr_in2 > 99 && jahr_in2<1000){DATUM +="0";}
    	if(jahr_in2 > 9 && jahr_in2<100){DATUM +="00";}
    	if(jahr_in2<10){DATUM +="000";}
    	DATUM += int2ascii(jahr_in2, DATUM);
    	//datum zusammenbasteln ENDE
    
    	return DATUM;
    }
    
    float Schueler::durchschnitt(string NAME, string FACH)
    {								//durchschnitt berechnen
    	int gesamt = 0;
    	float durch = 0;
    	string temp=" ";
    
    	ifstream ifl((NAME+string("/")+FACH).c_str());
    
    	while(temp!="")
    	{
    		getline(ifl,temp);
    		durch+=(temp[0]-48);
    		gesamt++;
    	}
    	ifl.close();
    	durch+=48;
    	gesamt--;
    	durch/=gesamt;
    
    	cout.precision(3);
    	cout << "\n Durchschnitt: " <<durch << "\n\n";
    
    	return durch;
    }
    
    void Schueler::anzeigen(string NAME, string FACH)
    {
    	string ausgabe=" ";
    
    	ifstream ifl((NAME+string("/")+FACH).c_str());
    
    	while(ausgabe!="")
    	{
    		getline(ifl,ausgabe);
    		cout << "\n " << ausgabe;
    	}
    	ifl.close();
    	durchschnitt(NAME, FACH);
    
    	pau();
    }
    
    void Schueler::anlegen(string NAME, string FACH, string NOTE)
    {
    //	ifstream ordner_da;
    	string DATUM;
    	Datum datums;
    
    	if(NOTE=="1"||NOTE=="2"||NOTE=="3"||NOTE=="4"||NOTE=="5"||NOTE=="6")
    	{
    		cout << "\n Tag: ";
    		cin >> datums.tag;
    		cout << "\n Monat: ";
    		cin >> datums.monat;
    		cout << "\n Jahr: ";
    		cin >> datums.jahr;
    
    		if(datums.istGueltig(DATUM))
    		{
    		//	ordner_da.open((NAME+string("\\fach.txt")).c_str(), ios::in);
    		//	if(ordner_da)
    		//	{
    	//		if(!(ordner_da.open((NAME + string("\\fach.txt")).c_str()))){
    			//	system((string("mkdir ")+NAME).c_str());
    		//		cout << " test";
    		//	}
    		//	else
    		//	{
    
    			cout << "\n ";
    			system((string("mkdir ")+NAME).c_str());
    
    			pau();
    
    			cls();
    
    			fstream erfassenSch;
    			erfassenSch.open("SchListe",ios::out | ios::app);
    			erfassenSch << (NAME + string("\n")).c_str();
    			erfassenSch.close();
    
    			fstream erfassenFach;
    			erfassenFach.open((NAME + string("/FachListe")).c_str(),ios::out | ios::app);
    			erfassenFach << (FACH + string("\n")).c_str();
    			erfassenFach.close();
    
    			fstream erfassenEintrag;
    			erfassenEintrag.open((NAME+string("/")+FACH).c_str(),ios::out | ios::ate);
    			erfassenEintrag << (NOTE + string(" ") + DATUM + string("\n")).c_str();
    			erfassenEintrag.close();
    			}
    		else
    		{
    			#ifdef unix
    			cout << "\n ungültiges Datum !\n ";pau();
    			#else
    			cout << "\n ungltiges Datum !\n ";pau();
    			#endif
    		}
    	}
    	else
    	{
    		#ifdef unix
    		cout << "\n ungültige Note !\n ";pau();
    		#else
    		cout << "\n ungltige Note !\n ";pau();
    		#endif
    	}
    }
    
    void Schueler::ergaenzen(string NAME, string FACH, string NOTE)
    {
    	string DATUM;
    	Datum datums;
    
    	if(NOTE=="1"||NOTE=="2"||NOTE=="3"||NOTE=="4"||NOTE=="5"||NOTE=="6")
    	{
    		cout << "\n Tag: ";
    		cin >> datums.tag;
    		cout << "\n Monat: ";
    		cin >> datums.monat;
    		cout << "\n Jahr: ";
    		cin >> datums.jahr;
    
    		if(datums.istGueltig(DATUM))
    		{
    			pau();
    
    			fstream ergaenzenFach;
    			ergaenzenFach.open((NAME + string("/FachListe")).c_str(),ios::out | ios::app);
    			ergaenzenFach << (FACH + string("\n")).c_str();
    			ergaenzenFach.close();
    
    			fstream ergaenzenEintrag;
    			ergaenzenEintrag.open((NAME+string("/")+FACH).c_str(),ios::out | ios::app);
    			ergaenzenEintrag << (NOTE + string(" ") + DATUM + string("\n")).c_str();
    			ergaenzenEintrag.close();
    		}
    		else
    		{
    			#ifdef unix
    			cout << "\n ungültiges Datum !\n ";pau();
    			#else
    			cout << "\n ungltiges Datum !\n ";pau();
    			#endif
    		}
    	}
    	else
    	{
    		#ifdef unix
    		cout << "\n ungültige Note !\n ";pau();
    		#else
    		cout << "\n ungltige Note !\n ";pau();
    		#endif
    	}
    }
    
    void Schueler::loeschen(string NAME)
    {
        #ifdef unix
        system(("rm -r " + NAME + "/*").c_str());
        #else
        system(("del " + NAME + "\\*").c_str());
        #endif
        system(("rmdir " + NAME).c_str());
    }
    
    void Schueler::ist_da()
    {
        ifstream istda;  
        string eintraege;
        istda.open("SchListe", ios::in);
        if(istda)
        {
    		#ifdef unix
    		cout << "\n vorhandene Schüler\n";
    		#else
    		cout << "\n vorhandene Schler\n";
    		#endif
    
    		while (!istda.eof())          
    		{
    			getline(istda, eintraege);      
    			cout << "\n " << eintraege;    
    		}
    	}
    }
    
    void Fach::ist_da(string NAME)
    {
        ifstream istda;  
        string eintraege;
    
        istda.open((NAME+string("/FachListe")).c_str(), ios::in);
    
        if(istda)
        {
    		#ifdef unix
    		cout << "\n vorhandene Fächer von " << NAME << "\n";
    		#else
    		cout << "\n vorhandene F„cher von " << NAME << "\n";
    		#endif
    
    		while (!istda.eof())          
    		{
    			getline(istda, eintraege);      
    			cout << "\n " << eintraege;    
    		}
    	}
    }
    

    Und über switch-case denke ich mal nach 😃



  • Die Schüler-Klasse sieht ja merkwürdig aus - legst du echt für jeden Schüler ein eigenes Verzeichnis auf Festplatte an?
    Und außerdem solltest du dort, wo du mit Zahlen rechnest, auch int's verwenden (z.B. für die Noten)

    Ansonsten: Schau doch mal die Fehlermeldungen durch, welche Funktion(en) der Linker nicht findet - das könnte schonmal ein erster Ansatz sein.



  • Das Programm läuft mitlerweile! Nun werde ich alles nochmal überarbeiten und über eure Vorschläge nachdenken!


Anmelden zum Antworten