Dankbank mit Index



  • Hi Leute,

    ich stehe mal wieder vor einem Problem und erbitte eure Hilfe. Ich soll ein Programm schreiben, dass wie eine Datenbankverwaltung funktioniert. Die ganzen Datensätze sollen lokal auf der Festplatte gespeichert werden. Die Daten sollen mittels eines Index angeprochen und ausgelesen werden. Der Index soll "Name" und "Position" enthalten. Im Speicher soll immer nur ein Datensatz liegen.

    Leider versteh ich nicht ganz wie ich das ganze umsetzen soll. Ich hoffe ich konnte mein Problem einigermaßen beschreiben und bitte um Hilfe. Danke.

    Gruß
    GiJoe

    P.S. Anbei noch ein Codeausschnitt was ich so zusammengeschrieben habe.

    struct sPerson //Vorlage für neue Datensätze
    {
    	char name[60];
    	char stadt[60];
    };
    
    void inputPerson() //neue Person hinzufügen
    {
    	FILE *fPtr;
    	sPerson *person;
    	person = (sPerson*) malloc(sizeof(sPerson));
    
    	printf("Name.....: ");
    	scanf("%s", person->name);
    	printf("Stadt....: ");
    	scanf("%s", person->stadt);
    
    	fPtr = fopen(PATH, "a");
    	fwrite(person, sizeof(sPerson), 1 ,fPtr);
    	fclose(fPtr);
    	free(person);
    	person = NULL;
    	system("cls");
    }
    


  • mit 'fseek', also z.b. fseek(fPtr, xsizeof(struct sPerson), SEEK_SET);* könnteste auf eine bestimmte struct in der datei zugreifen.
    🙂



  • scheinbar habe ich mein Anliegen doch nicht so richtig formuliert. Die ganzen Ein- und Ausgabefunktionen sind mir schon bekannt. Es soll wohl so sein, dass die kompletten Datensätze lokal auf der Festplatte liegen sollen und im Arbeitsspeicher soll ein Index lieben mit "Name" und "Position". Ich verstehe halt nicht wie ich das mit dem Index anstellen soll.

    Greetz GiJoe.



  • Wenn du keine Lust hast, sequentiell alle Datensätze zu durchsuchen, mußt du dir eine Art Baumstruktur (B+ Baum) aufbauen, die du zum Suchen nutzt.



  • Hi,

    GiJoe schrieb:

    Der Index soll "Name" und "Position" enthalten.

    Ich verstehe die oben zitierte Aussage nicht!

    Nehmen wir mal an, der Index ist gleich der Position, an dem der entsprechende
    Datensatz in der Datei gespeichert ist.
    Dann benötigst du eine Zuordnung zwischen Name und Index (=Position des
    Datensatzes), um dann mittels fseek direkt auf den Datensatz zugreifen zu
    können.

    Für diesen Zweck würde ich, wie CStoll es vorgeschlagen hat, einen
    Suchbaum (z.B. AVL-Baum) verwenden, den du zu Beginn des Programmstarts
    aufbaust, indem du einmal durch die gesamte Datenbank gehst, oder ihn
    ebenfalls in einer (gesonderten) Datei speicherst.

    Könntest du noch einmal genau deine Fragegestellung formulieren.

    Gruß mcr



  • Sers,

    ok ich versuchs mal ordentlich zu erklären. Zuerst mussten wir eine Datenbank mit doppelt verketteten Listen aufbauen. Anschließend hieß es: "Ok, jetzt machen wir dieselbe Datenbank nicht mit verketteten Listen, sondern so wie eine richtige Datenbank arbeitet."

    Die Erklärung dazu war folgende.

    struct sPerson
    {
    char name[60];
    char stadt[60];
    }
    

    so, ich hoffe so weit so gut.
    Nun hieß es die Daten "name" und "stadt" sollen lokal auf die Festplatte gespeichert werden. Das ist ja auch so weit kein Problem. Das ganze mit fopen, fseek, fclose, FILE usw.

    Ich verstehe bloß die Aussage von meinem Aufgabensteller nicht, dass man dazu noch einen Index braucht. Der Index soll angeblich auch ein struct sein z.B. sIndex mit folgenden Inhalten: "Name" und "Position". Damit müssten wir theoretisch zu diesem Aufbau kommen:

    struct sPerson // soll auf HDD gespeichert werden z.B. "PersonDatabase.bin"
    {
    char name[60];
    char stadt[60];
    }
    
    struct sIndex // soll im Arbeitsspeicher sein und dann immer den benötigten Datensatz von HDD auslesen.
    {
    char name[60];
    int position;
    }
    

    So, dass sind nun alle Informationen die ich habe. Leider hat mein Aufgabensteller die Angewohnheit einem nur so Info-Batzen hinzuwerfen.
    Mittlerweile hab ich ihn auch schon zweimal gefragt wie ich den dieses
    Problem anpacken soll und ich habe genau die selbe Erklärung bekommen wie am

    Das ist ja auch der Grund warum ich euch frage.

    Puh! Ich hoffe ich konnte es diesmal einigermaßen gut erklären und danke
    euch schonmal 1.000fach für eure Hilfe.

    Gruß

    GiJoe/junkon2005



  • So wie ich das verstehe, dient dein sIndex dazu, zu jedem Namen schnell
    die Position in der Datei zu finden, so dass du beim Suchen nicht jedesmal
    die gesamte Datei scannen mußt.

    Ich würde nun das Programm wie folgt aufbauen.

    1. Öffnen der Datenbank
    

    Hier scannst du einmal durch die gesamte Datenbank und erstellst ein Array
    (mit malloc Speicher anlegen, da du zur Kompilezeit nicht weißt, wieviele
    Elemente maximal enthalten sind), wo du jedem Namen eine Position zuweist.

    [PSEUDOCODE]
       int i = 0;
       while ((datensatz = datensatz lesen)) {
          new sIndex(datensatz.Name, i);
          ++i;
          array add(sIndex);
       }
    

    Mit Sicherheit ist es besser, anstelle von einem Array einen Suchbaum
    (B-Baum, AVL-Baum, etc.) zu wählen, damit ein anschließendes Suchen nur
    logarithmisch in Anzahl der Elemente zu realisieren ist.

    2. Menügesteuertes Arbeiten mit der Datenbank
    

    Ok, das bleibt dir mal überlassen.

    3. Datenbank bei Beenden schließen
    

    Du kannst dir auch im Schritt 1 das Scannen durch die Datenbank sparen,
    wenn du diese Informationen gesondert speicherst. Dann mußt du im 3.
    Schritt lediglich das Array speichern, da sich im 2. Schritt ja einiges
    an der Datenbank geändert haben kann.

    Ich hoffe, ich konnte dir hiermit weiterhelfen.

    Gruß mcr



  • vielen Dank für eure starke Mithilfe, dass hat mir sehr weitergeholfen.
    Jetzt weiß ich endlich wo ich ansetzen muss.

    Zitat: Die Gehirnwindungen eines Programmierers sind unantastbar.

    Gruß

    GiJoe/Junkon



  • Servus mitnander,

    so jetzt hab ich mal ne erste Version die sogar tatsächlich funktioniert.
    Wenn ich jetzt den sIndex auch noch sortiert bekomme wärs perfekt. Das
    soll aber nun nicht mehr euer Problem sein. Vielen Dank nochmal.

    void inputPerson()
    {
    	FILE *fPtr;
    	sData *pData = NULL;
    	pData = (sData*) malloc(sizeof(sData));
    	char *sortPtr = NULL;
    	sIndex temp[60];
    
    	//save input
    	printf("Name.....: ");
    	scanf("%s", pData->name);
    	printf("Stadt....: ");
    	scanf("%s", pData->stadt);
    
    	//save to HD (unsorted)
    	fPtr = fopen(PATH, "a");
    	fwrite(pData, sizeof(sData), 1 ,fPtr);
    	fclose(fPtr);
    
    	//save to Index (still unsorted)
    	strcpy(index[counter].name, pData->name);
    	index[counter].pos += sizeof(sData)*counter; 
    	counter++;
    
    	arraySort(index);
    
    	free(pData);
    	system("cls");
    }
    

    Gruß GiJoe



  • Sieht doch schon recht brauchbar aus (als Anfang) - ich hoffe, 'index' ist groß genug für deine Bedürfnisse (nur das "+=" sieht etwas unpassend aus).

    Aber: der Rückgabewert von malloc() wird nicht gecastet - und hier brauchst du noch nicht mal malloc() zu verwenden (eine lokale Variable sollte reichen).


Anmelden zum Antworten