Hilfe bei C - Datenbank Aufgabe - Checken von Programm



  • Hallo liebe Leute,

    ich habe ein Probleme ein C Programm vernünftig zum laufen zu bekommen und bin langsam am verzweifeln. Ich bin noch blutiger Anfänger im programmieren. Stehe jedoch kurz vor meinem Bachelorabschluss in Elektrotechnik und muss für Info2 ein Programm erstellen.
    Für mich ist das mein Endgegner=). Für Profis wohl eine Sache von max. einer halben Stunde Arbeit.

    Aufgabenstellung:

    Es geht darum eine einfache StudentenDatenbank zu programmieren die 20 Datensätze beinhalten soll. Dabei erfolgt die Speicherverwaltung statisch.
    Der Datensatz für einen Studenten soll beinhalten:
    - Name (max. 10 Zeichen)
    - Vorname (max. 10 Zeichen)
    - Matrikelnummer (max. 6 Zeichen)

    Es sollen folgende Operationen möglich sein:
    -Hinzufügen eines neuen Datensatzes
    -Suchen eines Datensatzes nach Name oder Matrikelnummer
    -Anzeigen eines vorhandenen Datensatzes
    -Ändern eines vorhandenen Datensatzes
    -Löschen eines vorhandenen Datensatzes

    Weiterhin sollen Listen ausgegeben werden, die wahlweise nach Name oder Matrikelnummer sortiert sind und wahlweise Name und Vorname oder nur die Matrikelnummer beinhalten.
    Bei allen Operationen sollen keine Datensätze umgespeichert werden. Die Verwaltung der Datenbank ist nur über Feldindizes oder nur über Adresszeiger vorzunehmen.
    Nach Jeder Änderung soll die Sortierung auf den neuen Stand gebracht werden, auch wenn kein Listenausdruck angefordert wird.

    Sooooo....
    Jetzt hab ich mit Hilfe eines Kollegen das Programm soweit geschrieben wie wir konnten. Jedoch komme ich da nicht mehr weiter. Beim erzeugen der Datenbank kommt ein Fehler "Zugriffsverletzung beim Schreiben an Position 0x00000000".

    Kann bitte irgendjemand so lieb sein und das Programm mal Checken? Ich kann es leider aufgrund des auftretenden Fehlers nicht vollständig Prüfen. Ich bräuchte halt jemanden der mal die Syntax durchguckt, das Programm auf Vollständigkeit Checkt und mir eventuelle Verbesserungsvorschläge gibt. Ist für einen geübten wohl nur eine Sache von 10 - 15 Minuten.
    Ich muss das Programm leider Gottes bis morgen Abend schon abgegeben haben.

    Vielen lieben Dank im Voraus. 🙂

    Hier die Datei. Die Aufgabenstellung ist im Ordner nochmal als PDF verfügbar.

    Info2.rar



  • Irgendein Zeiger ist NULL.

    Nimm den Debugger und schau nach, wo der stehen bleibt. Dann weisst du es genau.

    Alternativ kannst du ein paar Debugausgaben mit printf machen.
    Für Zeiger gibt es den Formatspecifier %p.

    Wieviel Zeilen hat denn dein Programm?



  • if (TempNextDS == NULL) *TempNextDS = Datenbank[j]; //Erster neuer Datensatz
    

    Was denkst du wird bei *TempNextDS passieren, wenn es NULL ist?

    Edit:
    Beim zweiten Mal kompilieren hat es gekracht: Makro-Redefinition:

    #define NULL ((void*)0)
    

    Beim Löschen eines Eintrages:

    if (ret <= 0 && ret >= MAXENTRYS)
    	ret = DB_Del(ret);
    

    Ich habe irgendwie das Gefühl, dass du hier das genaue Gegenteil meinst, auf das du hier testest. Die Bedingung ist true für Zahlen, die kleiner oder gleich 0 sind UND größer als 20 sind. Also für keine Zahlen.



  • Vielen Dank die Antworten.

    Ich habe irgendwie das Gefühl, dass du hier das genaue Gegenteil meinst.....

    Hast recht. So müsste es jetzt passen.

    if (ret >= 0 && ret <= MAXENTRYS)
        ret = DB_Del(ret);]"
    

    Was denkst du wird bei *TempNextDS passieren, wenn es NULL ist?

    Ich versteh um ehrlich zu sein die Sortierfunktion nicht ganz. Bzw. die Funktion des Nullzeigers in der Funktion. Den Abschnitt hat der Kollege programmiert. Jedoch hat er keine Zeit mir zu helfen.

    Was ist den an dem Code falsch?..bzw. wie wäre er den richtig auszuführen?
    Der ist wohl für die Speicherverweigerung zuständig.

    /*Sortieren nach Matrikelnummer oder Name*/
    
    void sortIT(bool sortbyMatrikelNr = false)
    {
    	int i,j;
    	datensatz *TempNextDS = NULL; //NullZeiger
    
    	//Sortierte Liste Leeren
    	memset(DB_SortiertnachName,0,sizeof(DB_SortiertnachName));
    
    	//Schleife für Anzahl sortierter Einträge
    	for (i = 0; i < MAXENTRYS; i++)
    	{
    		//Suchschleife nächster Datensatz
    		for (j = i; j < MAXENTRYS; j++)
    		{
    		   if ((DBBelegt[(j/8)] & (0x01 << (j % 8))) == 1) //nächsten belegten Datensatz suchen
    		   {
    			  if (TempNextDS != NULL) *TempNextDS = Datenbank[j]; //Erster neuer Datensatz
    
    			  //Sortieren wir Name oder Matrikelnummer?
    			  if (sortbyMatrikelNr)
    				  if (strcmp(TempNextDS->matrikel,Datenbank[j].matrikel) < 0) *TempNextDS = Datenbank[j]; //Prüfung, welcher String weiter vorne im lexikon steht.
    			  else
    				  if (strcmp(TempNextDS->name,Datenbank[j].name) < 0) *TempNextDS = Datenbank[j]; //Prüfung, welcher String weiter vorne im lexikon steht.
    		   }
    		}
    
    		if (TempNextDS == NULL) return; //Kein weiterer Datensatz -> Abbruch der Sortierung
    
    		DB_SortiertnachName[i] = TempNextDS; //Adresse des nächten gefundenen Datensatzes wird in eine Liste geschrieben. 
    		TempNextDS = 0;						 //Nullpointer setzen.
    	}
    }
    
    void sortbyName()
    {
    	sortIT();
    }
    
    void sortbyNr()
    {
    	sortIT(true);
    }
    

  • Mod

    -Globale Variablen sind fast immer Müll. Hier sehe ich kein Anzeichen, dass dies anders ist.
    -Dein Code ist C++, nutzt aber keine C++-Features (bis auf eines (Defaultparameter), weswegen es eben kein C mehr ist). Wenn du schon C++ machst, dann kannst du dir das Leben auch wesentlich einfacher machen, indem du es richtig nutzt.
    -Compilerwarnungen aktivieren. Deine Zeilen 22-25 machen nicht das, was du denkst.
    -Selbst wenn sie richtig wären, sieht die ganze Logik von 19-25 nach Schrott aus:

    Wenn (Voraussetzung für A) Tue A;
    Wenn (B) Tue A;  // Voraussetzung für A wurde hier übrigens nicht geprüft
    Wenn (C) Tue A;
    

    Irgendwie Unsinn, oder?
    -Auch die restliche Logik sieht nach Schrott aus. Woher kommt TempNextDS? Wann und wieso wird es auf NULL gesetzt? Was treibst du mit DB_SortiertnachName?

    Tut mir leid, der Code ist absoluter Müll. Klingt hart, muss man aber so sagen. Da ist nichts zu retten.



  • @SeppJ

    Vielen Dank für deine kritischen Worte=))..
    Wie gesagt ich bin totaler Anfänger in Programmieren. Bin erst 2 Wochen dran.
    Irgendwann werd ich auch noch besser und in der Lage sein andere zu korrigieren=)

    Das Programm soll in C geschrieben werden auch wenn es vllt in C++ einfacher wäre. Muss aber erstmal C lernen.
    Ich verstehe hier nicht wie ich eine vernünftige Sortierfunktion hinbekomme. Es sollen 20 Datensätze in einer Datenbank wahlweise nach Matrikelnummer oder nach Namen Sortiert werden. Welchen Sortieralgorithmus schlägst du vor?.
    Sollen es zwei unabhängigen sein oder geht das auch in einem? Bubblesort?! Quicksort?!..habe ich noch nie angewendet.


  • Mod

    Wenn du seit 2 Wochen programmierst, ist die Aufgabe viel zu schwer. Besonders da du anscheinend nicht gerade den besten Stil gelehrt bekommen hast. Wenn die Aufgabe ist, selber einen Sortieralgorithmus zu schreiben, nimm den aus der Aufgabenstellung. Wenn die Aufgabe ist, etwas zu sortieren, egal wie, benutz die Standardbibliothek.

    Das Programm soll in C geschrieben werden auch wenn es vllt in C++ einfacher wäre.

    Du hast aber C++ gemacht (wenn auch nur in einer Zeile). Das Programm kann von einem C-Compiler nicht übersetzt werden. Man hat euch die Sprache falsch beigebracht.



  • Das ist ja nicht sein Code:

    IchBraucheHilfe schrieb:

    Ich versteh um ehrlich zu sein die Sortierfunktion nicht ganz. Bzw. die Funktion des Nullzeigers in der Funktion. Den Abschnitt hat der Kollege programmiert. Jedoch hat er keine Zeit mir zu helfen.

    Evtl. kann der Kollege ja schon mehr. Zumindest in C++


  • Mod

    DirkB schrieb:

    Evtl. kann der Kollege ja schon mehr. Zumindest in C++

    Bloß dass der Code komplett falsch ist und der C++-Teil vermutlich aus Unwissen eingefügt wurde. 😞



  • Evtl. kann der Kollege ja schon mehr. Zumindest in C++

    Der Kollege kann auf jeden Fall mehr. Ist aber schon ne Zeitlang raus aus der Programmierung. Er hat das Programm in zwei Stunden geschrieben und hatte leider keine Zeit mehr um das Programm auf Fehler zu prüfen und mir das Ding großartig zu erklären. Meinte ich soll den Rest selbst machen. Ich hab im Prinzip nur den Hauptteil mit den Ein- und Ausgaben geschrieben und ein paar Kommentare gesetzt. =)..
    Die Funktionen sind alle vom Kollegen. Ich versuch diese nun nachzuvollziehen und korrigieren. Was für einen Anfänger leider nicht gerade einfach ist=)
    Würd das Programm echt gern vernünftig zum laufen bekommen. Auch wenns vllt für meinen Schein in Info2 reichen würde. Ich wills halt lernen. Im anstehenden Berufsleben werde ichs wohl auch gebrauchen können.

    Deswegen bin ich für jede Hilfe und Erklärung dankbar=)



  • Ich ziehe meinen Hut vor jedem der programmieren gelernt hat. Erstaunlich durch welchen Nervenkitzel man da durchgehen muss bis man es richtig gelernt hat. Kostet echt viele Nerven und erfordert Durchhaltevermögen ohne Ende oO. Mich bringt es immer wieder zur Verzweiflung 😃


  • Mod

    Als ich das gerade mal implementieren wollte: Die Aufgabe ist ja beknackt! Einerseits wird an vielen Stellen ein Kindergarten gemacht, wie maximal 20 Datensätze (damit man es sich leicht machen kann und ein statisches Array nutzen kann?), andererseits bedeutet die Anforderung, dass man niemals umspeichern darf letztendlich doch, dass man eine anspruchsvollere Datenstruktur (Baum, Liste) benötigt. Soll man jetzt eine verkettete Liste in dem Array implementieren? Das macht die Aufgabe ja gleich unnötig schwerer, da man nicht nur die Schwierigkeit hat, die Datenstruktur zu implementieren, sondern dabei noch nicht einmal bequem die normale dynamische Speicherverwaltung nutzen kann, sondern sich quasi ein eigenes malloc für das Array schreiben muss! (Oder eine künstliche Beschränkung einer ge-malloc-ten Struktur auf 20 Elemente einführen 👎 )
    Weiterhin kann man dadurch nicht einmal das interne qsort benutzen, ohne auf globale Zustände für den Callback angewiesen zu sein. Also muss man entweder schlecht selber sortieren oder mit globalen Variablen arbeiten.

    Wer diese Aufgabe gestellt hat, ist entweder ein Sadist; oder er hat keine Ahnung, was er da wirklich verlangt hat. Die scheinbaren Erleichterungen gehen jedenfalls voll nach hinten los 😮 .

    Die Aufgabe mache ich dann doch nicht mal eben in einer halben Stunde. Da sitzt man ja mindestens einen halben Tag dran, selbst wenn man weiß, was man tut. Und wenn man nicht ganz genau weiß, was man tut, dann ist die Aufgabe unmöglich bei diesen Anforderungen. Dafür muss man sich ja selbst in exotischen Gebieten bestens auskennen. Eigene Datenstrukturen, eigene Speicherverwaltung (oder die "normale" manuelle Speicherverwaltung ist auch schon schwer genug) und eigene Sortieralgorithmen? Nach 2 Wochen?



  • Hahaha..:D

    @SeppJ
    Darf ich bitte dein Kommentar 1 zu 1 kopieren und meinem Prof per Mail schicken?:D
    Vllt macht er sich dann für die nächsten Studenten mehr Gedanken bei Erstellen einer Aufgabe.
    Er hat mir heute eine Verlängerung der Abgabefrist des Programms bis Montag gegeben. So wies aussieht wirds wohl selbst bis Montag nix. Mein Wochenende ist zumindest schonmal im Arsch 😃


  • Mod

    IchBraucheHilfe schrieb:

    Darf ich bitte dein Kommentar 1 zu 1 kopieren und meinem Prof per Mail schicken?:D

    Meinetwegen. 🙂

    Jedenfalls hatte ich ehrlich vor, die Aufgabe mal eben zu programmieren, um zu gucken, wo da die Schwierigkeiten sind. Weil sie auf den ersten Blick so einfach aussieht. Aber da das tatsächlich wirklich schwer ist und ich wohl mehrere Stunden bräuchte (und ich weiß bereits, was ich tun müsste. Es ist nur sehr viel Arbeit. Wenn ich noch nicht so viel Übung hätte, bräuchte ich wohl das ganze Wochenende bis das Ding sauber programmiert ist und korrekt läuft), habe ich mich mal dagegen entschieden. Wir können hier im Forum natürlich weiterhin konkrete Fragen beantworten, aber nach dem Code den du gezeigt hast, musst du dein Projekt eigentlich komplett nochmal überarbeiten (und wahrscheinlich diesen Vorgang noch mehrmals wiederholen). Damit das jemand komplett für dich programmiert, müsste da schon mehr Anreiz sein, als nur der Wille, jemandem zu helfen.



  • SeppJ schrieb:

    Einerseits wird an vielen Stellen ein Kindergarten gemacht, wie maximal 20 Datensätze (damit man es sich leicht machen kann und ein statisches Array nutzen kann?), andererseits bedeutet die Anforderung, dass man niemals umspeichern darf letztendlich doch, dass man eine anspruchsvollere Datenstruktur (Baum, Liste) benötigt.

    Moment.
    Eine Liste mit Zeigern auf die Daten muss doch genügen, oder?

    #define SIZE 20
    #define NAME_LEN 10
    #define NUMBER_LEN 6
    
    struct db{
      struct student{
        char family_name[NAME_LEN+1];
        char given_name[NAME_LEN+1];
        char student_number[NUMBER_LEN+1];
      } data[SIZE];
      struct student *index[SIZE];
      int max; // soviele stehen schon drin
    };
    
    int compare_name_asc(const void *a, const void *b){
      const struct student *aa = *((const struct student**)a);
      const struct student *bb = *((const struct student**)b);
      return strcmp(aa->family_name, bb->family_name);
    }
    
    void sort_by_name(struct db *db){
      qsort(db->index, db->max, sizeof(*db->index), compare_name_asc);
    }
    

  • Mod

    Jetzt mach mal Löschen und Einfügen, ohne etwas in data zu verschieben.



  • Was sich der Aufgabensteller real vorstellt 😕

    Eventuell wie einige Datenbanken vor vielen Jahren? Da wurden die Datensätze z.B. nur als gelöscht markiert und neue, zusätzliche nur angehängt.

    Irgend wie erinnert mich die Aufgabe an DBase und ähnliche Programme?

    MfG f.-th.



  • Hab auch mal angefangen…

    SeppJ schrieb:

    Als ich das gerade mal implementieren wollte: Die Aufgabe ist ja beknackt!

    Jo.

    SeppJ schrieb:

    Einerseits wird an vielen Stellen ein Kindergarten gemacht, wie maximal 20 Datensätze (damit man es sich leicht machen kann und ein statisches Array nutzen kann?), andererseits bedeutet die Anforderung, dass man niemals umspeichern darf letztendlich doch, dass man eine anspruchsvollere Datenstruktur (Baum, Liste) benötigt.

    Nee, nur ein Index.
    "Bei allen Operationen sollen keine Datensätze umgespeichert werden. Die Verwaltung der Datenbank ist nur über Feldindizes oder nur über Adresszeiger vorzunehmen."
    Ähm, sogar zwei Indizes!
    "Nach Jeder Änderung soll die Sortierung auf den neuen Stand gebracht werden, auch wenn kein Listenausdruck angefordert wird."

    SeppJ schrieb:

    Soll man jetzt eine verkettete Liste in dem Array implementieren?

    Dann würde ich mir noch ein drittes int-Array (als stack/vector) gönnen und mir dort die noch freien Plätze merken.

    SeppJ schrieb:

    Weiterhin kann man dadurch nicht einmal das interne qsort benutzen, ohne auf globale Zustände für den Callback angewiesen zu sein. Also muss man entweder schlecht selber sortieren oder mit globalen Variablen arbeiten.

    qsort bietet sich hier eh nicht an, weil nur 20 Elemente und nur eines verändert wurde.

    SeppJ schrieb:

    Wer diese Aufgabe gestellt hat, ist entweder ein Sadist; oder er hat keine Ahnung, was er da wirklich verlangt hat. Die scheinbaren Erleichterungen gehen jedenfalls voll nach hinten los 😮 .

    Die scheinbaren Erleichterungen störten mich keineswegs. Daß man zwei Indizes führen muss, zwingt dazu, daß man sie überhaupt führt und nicht schummeln kann. Da gehe ich mal davon aus, daß der Prof das ausführlich an der Tafel vorgemacht hat. Nervig ist, daß man unglaublich viel Code tippen muss, bevor man den ersten Testlauf machen kann. Bei mir main, menu, hinzufügen, anzeigen und die Strukturen… ~(habs vielleicht in c++ angefangen)~

    #include <stdio.h>
    #include <stdbool.h>
    
    typedef struct{
    	char name[11];
    	char vorname[11];
    	char matrikelnummer[7];
    } Student;
    
    void sEingabe(Student* s){
    	printf("Name: ");scanf("%s",s->name);
    	printf("Vorname: ");scanf("%s",s->vorname);
    	printf("Matrikelnummer: ");scanf("%s",s->matrikelnummer);
    }
    
    typedef struct{
    	Student studenten[20];
    	int anzahl;
    	int nameIndex[20];
    	int matrikelnummerIndex[20];
    	int freie[20];
    } StudentenVerwaltung;
    
    void svInit(StudentenVerwaltung* sv){
    	sv->anzahl=0;
    	int i;
    	for(i=0;i!=20;++i)
    		sv->freie[i]=i;
    }
    
    void svHinzufuegen(StudentenVerwaltung* sv){
    	int platz=sv->freie[sv->anzahl];
    	++sv->anzahl;
    	sEingabe(&sv->studenten[platz]);
    }
    
    void svListeAnzeigen(StudentenVerwaltung* sv){
    }
    
    bool svMenu(StudentenVerwaltung* sv){
    	printf(
    "1) -Hinzufügen eines neuen Datensatzes\n"
    "2) -Suchen eines Datensatzes nach Name oder Matrikelnummer\n"
    "3) -Anzeigen eines vorhandenen Datensatzes\n"
    "4) -Ändern eines vorhandenen Datensatzes\n"
    "5) -Löschen eines vorhandenen Datensatzes\n"
    "6) -Liste ausgeben sortiert nach Name oder Matrikelnummer\n"
    "0) -Ende\n"
    	);
    	int eingabe;
    	scanf("%i",&eingabe);
    	switch(eingabe){
    	case 1:
    	svHinzufuegen(sv);
    	return true;
    	case 0:
    	return false;
    	default:
    	printf("Falsche Eingabe\n");
    	return true;
    	}
    }
    
    int main(){
    	StudentenVerwaltung sv;
    	svInit(&sv);
    	while(svMenu(&sv))
    		;
    	return 0;
    }
    

    Und dann hat mich die Aufgabenstellung schlicht verlassen:
    "Es sollen folgende Operationen möglich sein:
    -Hinzufügen eines neuen Datensatzes"
    ok.

    "-Suchen eines Datensatzes nach Name oder Matrikelnummer"
    Suchen ohne Anzeige?

    "-Anzeigen eines vorhandenen Datensatzes"
    Anzeigen als anderer Menupunkt? Soll ich einen Datencursor mitführen?

    "-Ändern eines vorhandenen Datensatzes"
    Cursor?

    -Löschen eines vorhandenen Datensatzes
    Cursor?

    Nu hab ich die Lust verloren.

    Ach, statt Cursor gehts auch so.
    "-Hinzufügen eines neuen Datensatzes"
    freien Platz poppen
    dort eingabe aufrufen
    einen insertion-sort-schritt

    "-Suchen eines Datensatzes nach Name oder Matrikelnummer"
    (ist kein menupunkt)
    name oder matrikelnummer fragen
    danach suchen (binär, wenn man die 1 erzwingen will)

    "-Anzeigen eines vorhandenen Datensatzes"
    suchen aufrufen
    anzeigen aufrufen

    "-Ändern eines vorhandenen Datensatzes"
    löschen aufrufen
    hinzufuegen aufrufen

    -Löschen eines vorhandenen Datensatzes
    suchen aufrufen
    den aus dem index kicken (linear durchgehen)
    freien platz pushen

    SeppJ schrieb:

    Und wenn man nicht ganz genau weiß, was man tut, dann ist die Aufgabe unmöglich bei diesen Anforderungen.

    Sehe ich auch so. Als Lernprojekt eher ungeeignet. Man rennt ja ständig mit der Nase gegen eine Betonwand. Man kann's entweder gleich oder man kann 100 Stunden reinblasen und es wird trotzdem nix. Also "besorgt" man sich die Lösung von älteren Semestern, weil es gar nicht anders geht.

    SeppJ schrieb:

    Dafür muss man sich ja selbst in exotischen Gebieten bestens auskennen. Eigene Datenstrukturen, eigene Speicherverwaltung (oder die "normale" manuelle Speicherverwaltung ist auch schon schwer genug) und eigene Sortieralgorithmen? Nach 2 Wochen?

    Oder mehrere Jahre auf dem 64-er programmiert haben. 🤡



  • SeppJ schrieb:

    Jetzt mach mal Löschen und Einfügen, ohne etwas in data zu verschieben.

    Wenn meine Struktur so initialisiert ist, dass anfänglich jeder Zeiger index[i] auf das korrespondierende Feld data[i] zeigt, muss ich nur Einträge in index vertauschen.

    int create(const struct student *s, struct db *db){
      if(SIZE<=db->max)
        return 0;
      memcpy(db->index[db->max], s, sizeof(struct student));
      ++db->max;
      return 1;
    }
    
    int empty(const struct db *db){
      return db->max==0;
    }
    
    void swap(struct student **a, struct student **b){
      struct student *c=*a;
      *a=*b;
      *b=c;
    }
    
    int delete(int which, struct db *db){
      assert(0<=which && !empty(db));
      if(db->max<=which)
        return 0;
      --db->max;
      swap(&db->index[which], &db->index[db->max]);
      return 1;
    }
    

    Anspruchsvolle Aufgabe aber nicht total beknackt.

    Jetzt hol ich mir neuen Kaffee und les mal 'ne Stunde was volkard so schreibt. 🙂



  • "-Suchen eines Datensatzes nach Name oder Matrikelnummer"
    Suchen ohne Anzeige?

    "-Anzeigen eines vorhandenen Datensatzes"
    Anzeigen als anderer Menupunkt? Soll ich einen Datencursor mitführen?

    "-Ändern eines vorhandenen Datensatzes"
    Cursor?

    -Löschen eines vorhandenen Datensatzes

    Also ich habe mir das so vorgestellt:

    Anzeige eines vorhandenen Datensatzes und Suche eines vorhandenen Datensatzes gehört für mich in einen Unterpunkt. Ich suche und gebe das gefundene aus.
    Und bei der Ausgabe von listen werden ja auch die vorhandenen Datensätze ausgegeben.

    Bei den sortierten Listen habe ich noch nix, da ich mit Sortierfunktion noch kämpfe.

    Das ist jetzt nur die main Datei. die Struktur habe ich in einer headerdatei definiert.

    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	bool b;
    	int  ret;
    	char auswahl ='u';	
    
    	char TempInput[20]; // Zwischenspeicher erstellen
    
    	datensatz EinEintrag;
    
    DB_Init(); //Datenbank initialisieren
    
    while (auswahl != 'E'){
    	    system ("cls");															
    		printf("\n\t*** Stundentendatenbank ***\n");
    
    		printf("\n1) Hinzufuegen eines neuen Studenten");
    		printf("\n2) Liste aller vorhandenen Studenten Anzeigen");
    		printf("\n3) Suchen eines vorhandenen Studenten");
    		printf("\n4) Aendern der Daten eines vohandenen Studenten");
    		printf("\n5) Loeschen eines vorhandenen Studenten");
    		printf("\nE) Ende");
    
    		printf("\n\nIhre Auswahl:");
    		scanf("%c",&auswahl);
    		fflush (stdin) ;														
    	    system ("cls");
    
    		ret = 0;
    		b = false;
    
    /********************************* Auswahlverfahren für Operationen *****************************************/
    
    		switch(auswahl){
    
    /* Case_1 ******************** Auswahl für HINZUFÜGEN eines Datensatzen *************************************/
    
    		case'1':
    
    			memset(&EinEintrag,'\0',sizeof(datensatz));
    
    			printf("\n\t*** Hinzufuegen eines neuen Datensatzes ***\n\n");
    
    			printf("\nBitte den Namen eingeben:");			
    			memset(&TempInput,'\0',sizeof(TempInput)); //Zwischenspeicher leeren
    			scanf("%s",&TempInput);					   //Eingabe in Zwischenspeicher scannen
    			fflush (stdin) ;						   //Puffer leeren
    			strncpy_s(EinEintrag.name,TempInput,NAMEFIELDLEN-1); //Kopiert von TempInput in Datensatz Name
    
    			printf("\nBitte den Vornamen eingeben:");  
    			memset(&TempInput,'\0',sizeof(TempInput)); //Zwischenspeicher leeren
    			scanf("%s",&TempInput);					   //Eingabe in Zwischenspeicher scannen
    			fflush(stdin) ;							   //Puffer leeren
    			strncpy_s(EinEintrag.vorname,TempInput,NAMEFIELDLEN-1); //Kopiert von TempInput in Datensatz Vorname
    
    			printf("\nBitte die Matrikelnummer eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput)); //Zwischenspeicher leeren
    			scanf("%s",&TempInput);					   //Eingabe in Zwischenspeicher scannen
    			fflush (stdin) ;						   //Puffer leeren
    			strncpy_s(EinEintrag.matrikel,TempInput,MATRIKELFIELDLEN-1); //Kopiert von TempInput in Datensatz Matrikel
    
                // Hinzufügen / ADD 
    			ret = DB_Add(&EinEintrag);
    
    			break;				
    
    /* Case_2 ******************* Auswahl Ausgeben von Liste aller Datensätze ************************************/	
    
    		case'2':
    
    			char chooseList;
    
    			while (chooseList != 'E'){
    					system ("cls");															
    					printf("\n\t*** Liste aller Studenten ausgeben ***\n");
    
    					printf("\n1) Liste sortiert nach Name ausgeben");
    					printf("\n2) Liste sortiert nach Matrikelnummer ausgeben");
    					printf("\nE) Ende");
    
    					printf("\n\nIhre Auswahl:");
    					scanf("%c",&chooseList);
    					fflush (stdin) ;														
    					system ("cls");
    
    					ret = 0;
    
    			switch(chooseList){
    
    			case '1':
    
    				printf("\Liste sortiert nach Name ausgeben\n\n");
    
    				// Ausgeben 
    				if (ret == DBOK)
    				{
    
    				printf("\nListe sortiert nach Name:"); 
    
    				//Hier Ausgabe sortierte Liste nach Namen hinzufügen
    				}
    				break;
    
    			case '2':
    
    				printf("\Liste sortiert nach Matrikelnummmer ausgeben\n\n");
    
    				// Ausgeben
    				if (ret == DBOK)
    				{
    				printf("\nListe sortiert nach Matrikelnummer:"); 
    				//Hier Ausgabe sortierte Liste nach Namen hinzufügen
    				}
    
    				break;
    			}
    		}
    /* Case_3 ******************* Auswahl für SUCHEN eines Datensatzen *****************************************/
    
    		case'3':
    			printf("\n\t*** Suchen eines Studenten in der Datenbank ***\n\n");
    
    			printf("\nBitte Namen oder Matrikelnummer eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%s",&TempInput);
    			fflush (stdin) ;
    
    			ret = DB_Search(&TempInput[0], b);  //Suchen 
    
    			// Ausgeben 
    			if (ret < DB_ENTRY_NOTFOUND)
    				ret = DB_Get(ret,&EinEintrag);
    
    			if (ret == DBOK)
    			{
    				printf("\nGefundener Student:"); 
    				printf("\nVorname : %s",EinEintrag.vorname);
    				printf("\nName    : %s",EinEintrag.name);
    				printf("\nMatrikel: %s",EinEintrag.matrikel);
    			}
    			break;
    
    /* Case_4 ******************* Auswahl für ÄNDERN eines Datensatzen ****************************************/	
    
    		case'4':
    
    			printf("\n\t*** Aendern der Daten eines Vorhandenen Studenten ***\n\n");
    
    			printf("\nBitte Name oder Matrikelnummer eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%s",&TempInput);
    			fflush (stdin) ;
    
    			// Suchen 
    			ret = DB_Search(&TempInput[0], true);
    
    			//Ausgeben
    			if (ret < DB_ENTRY_NOTFOUND)
    				ret = DB_Get(ret,&EinEintrag);
    
    			if (ret == DBOK)
    			{
    				printf("\nGefundener Student:"); 
    				printf("\nVorname : %s",EinEintrag.vorname);
    				printf("\nName    : %s",EinEintrag.name);
    				printf("\nMatrikel: %s",EinEintrag.matrikel);
    			}		
    			//Ändern
    			printf("\nIhre Aenderung Bitte:\n");
    
    			printf("\nBitte den neuen Namen eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%s",&TempInput);
    			fflush (stdin) ;
    			strncpy_s(EinEintrag.name,TempInput,NAMEFIELDLEN-1);
    
    			printf("\nBitte den neuen Vornamen eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%s",&TempInput);
    			fflush (stdin) ;
    			strncpy_s(EinEintrag.vorname,TempInput,NAMEFIELDLEN-1);
    
    			printf("\nBitte die neue Matrikelnummer eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%s",&TempInput);
    			fflush (stdin) ;
    			strncpy_s(EinEintrag.matrikel,TempInput,MATRIKELFIELDLEN-1);
    
    			break;
    /* Case_5 ******************* Auswahl für LÖSCHEN eines Datensatzen ****************************************/
    
    		case'5':
    			printf("\n\t*** Loeschen eines vorhandenen Studenten ***\n\n");
    
    			printf("\nBitte Namen oder Matrikelnummer eingeben:"); 
    			memset(&TempInput,'\0',sizeof(TempInput));
    			scanf("%i",&ret);
    			fflush (stdin) ;
    
    			//Ausgeben 
    			if (ret >= 0 && ret <= MAXENTRYS)
    				ret = DB_Del(ret);
    			break;
    /* Case_E *********************************** Ende***********************************************************/		
    		case'E':
    			printf("\nEnde\n\n");
    			break;
    
    		default:
    			printf("\nFalsche Eingabe\n");
    		} 
    
    /********************************* Auswertung des Fehlercodes ********************************************/
    
    		switch (ret)
    		{
    		case DBOK:				
    			printf("\nDatenbank OK!\n");
    			break;
    		case DB_ENTRY_NOTFOUND:	
    			printf("\nEintrag nicht gefunden!\n");
    			break;
    		case DB_PARAM_NULL:		
    			printf("\nDaten ungültig!\n");
    			break;
    		case DB_NOENTRY:
    			printf("\nKeinen Eintrag gefunden!\n");
    			break;
    		case DB_FULL:
    			printf("\nDatenbank voll!\n");
    			break;
    		default:
    			printf("\n..und wenn sie nicht gestorben sind...\n");
    			break;
    		}
    
    		system ("pause");
    
    	 } 
    
    	return 0;
    }
    }
    

Log in to reply