Hilfe bei C - Datenbank Aufgabe - Checken von Programm



  • 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;
    }
    }
    


  • IchBraucheHilfe schrieb:

    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.

    Vieeel Code
    

    Da ist aber keine Frage. Wenn Du eine konkrete Frage hast: stell sie.

    Aber was nutzt es überhaupt hier zu diskutieren, wenn Dein Kollege das gesamte Herzstück geschrieben hat?
    Wenn wir Dir sagen: Du könntest das so und so machen, kracht es ja an allen Ecken und Enden in seinem Code.
    Eigentlich würde ich sagen wegschmeissen und neu machen - evtl. schaffst Du dann nicht mehr die gesamte Aufgabe aber den Teil den Du hast verstehst Du auch.



  • Oh, Microsoft-C.

    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));
                scanf("%s",&TempInput);                    //Hier unbedingt noch mal sehen ob das so soll?
                fflush (stdin) ;                           //Der Microsoft-Weg
    

    Musst du alles in die Main packen?
    Wenn du den Quelltext in kleine Funktionen aufteilst, kann man das besser lesen, testen und du hast schneller kleine Erfolgserlebnisse. Dann kannst du dich besser auf deine Problem-Baustellen im Quellcode konzentrieren.



  • scanf("%s",&TempInput);  //Hier unbedingt noch mal sehen ob das so soll?
    

    Was ist daran falsch?.

    So wie ich das verstehe:

    Es wird ein Zwischenspeicher "TempInput" erstellt. Dieser wird Anfangs gelernt. Nach Aufforderung einen
    Namen einzugeben wird der eingegebene String in den Zwischenspeicher kopiert und von dort an den datensatz -> Name übergeben.
    Oder sehe ich das falsch?

    Meine Fragen hierzu:

    Was bedeutet die -1 beim Ausdruck -> "NAMEFIELDLEN-1"?!

    Das Eintragen in die Datenbank funktioniert soweit ganz gut.

    char TempInput[255]; // Zwischenspeicher erstellen
    datensatz EinEintrag;
    
    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
    
                // Hinzufügen
    			ret = DB_Add(&EinEintrag);
    
    extern int DB_Add(datensatz *entry);  //steht im Header
    

    Und die Funktion für das Hinzufügen von Datensätzen:

    int DB_Add(datensatz *entry)
    {
    	int i;
    	if (entry == NULL) return DB_PARAM_NULL;
    
    	for (i = 0; i < MAXENTRYS; i++)
    	{
    		//Wenn Bedingung erfüllt: Datensatz ist frei
    		if ((DBBelegt[(i/8)] & (0x01 << (i % 8))) == 0) break; //Abbruch der Suchschleife nach freiem Datensatz
    	}
    
    	if (i == MAXENTRYS) return DB_FULL; //Datenbank voll. Keinen freien Eintrag gefunden.
    
    	//Eintragen:
    	memcpy(&Datenbank[i],entry,sizeof(datensatz));
    	DBBelegt[(i/8)] |= (0x01 << (i % 8));  //Als belegt markieren
    
    	//Sortieren:
    	//sortbyName();
    	//sortbyNr();
    
    	return DBOK;
    }
    

    Was hat es mit dem Merker auf sich?

    char DBBelegt[(MAXENTRYS/8)+1]; //Merker belegte Datensätze: (Bitcodiert)
    

    Kann mir hier einer diese Bedingung erklären?:

    if ((DBBelegt[(i/8)] & (0x01 << (i % 8))) == 0) break;
    


  • IchBraucheHilfe schrieb:

    f.-th. schrieb:

    scanf("%s",&TempInput);  //Hier unbedingt noch mal sehen ob das so soll?
    

    Was ist daran falsch?.

    So wie ich das verstehe: ......

    Du beschreibst was passieren soll, nicht was passiert.

    Hier nochmal die Definition von TempInput

    char TempInput[20]; // Zwischenspeicher erstellen
    

    Jetzt schaust du nochmal in deinen Unterlagen nach, wie das mit scanf, %s, Arrays und dem & ist.

    IchBraucheHilfe schrieb:

    Was bedeutet die -1 beim Ausdruck -> "NAMEFIELDLEN-1"?!

    Einen Weniger.

    Da du die Definition von NAMEFIELDLEN nicht mitgeliefert hast. kann ich dir den genauen Wert nicht sagen.
    Entweder ist NAMEFIELDLEN ein Makro (#define), eine Variable oder Konstate.
    Zumindest steht es für einen Zahlenwert.
    In einem C-String ist das letzte Zeichen '\0'. Und dafür muss halt Platz übrig sein.



  • IchBraucheHilfe schrieb:

    char DBBelegt[(MAXENTRYS/8)+1]; //Merker belegte Datensätze: (Bitcodiert)
    

    Kann mir hier einer diese Bedingung erklären?:

    if ((DBBelegt[(i/8)] & (0x01 << (i % 8))) == 0) break;
    

    Das ist ein Array von char, und jeweils ein char besitzt 8 bits, die für jeweils einen "slot" in Deiner Datenbank stehen(*). Wenn da was drin steht wird das Bit gesetzt sonst genullt.

    Die Bedingung ist ein wenig Bitfriemelei, damit ein Bit ausgelesen wird.

    Schau Dir die "bitwise" Operatoren an, wenn Du mehr wissen willst.

    Zur veranschaulichung:

    #include <stdio.h>
    
    #define MAX 20
    
    char markers[(MAX+7)/8] = { 0 };
    
    void print(){
      for(size_t i=0; i<sizeof(markers)*8; ++i)
        printf("%i", markers[i/8] & 0x01<<i%8 ? 1 : 0);
      puts("");
    }
    
    void mark_slot(int i){
      markers[i/8] |= 0x001<<i%8;
    }
    
    int main(){
      print();
      mark_slot(7);
      mark_slot(9);
      mark_slot(11);
      print();
    }
    

    So setzt Dein Kollege die Bedingung "keine Datensätze sind zu verschieben" um.

    (*) Das array ist u.U. einen char zu lang, aber das ist egal.


Anmelden zum Antworten