Aus einer Structure löschen?



  • Ich schreibe gerade an einer Art DB-Programm, wo Bücher verwaltet werden sollen. Im Programm läuft alles über eine Structure, von der nur am Anfang und am Ende von/in eine Textdatei geschrieben wird. Es klappt auch alles so ganz gut, aber wenn ich jetzt einen Eintrag in der Structure löschen will, wie mach ich das am besten. Ich habe jetzt schon den Inhalt der Structure mit dem nachfolgenden Wert überschreiben lassen, habe jetzt aber immer den letzten Wert (bzw. Werte) doppelt. Wird irgendwie klar, was ich meine?
    Die Funktion:

    void daten_loeschen()
    {
    int z;
    if (datei == 0 ) 
        {
        lesen();
        }
    z = (y-1);
    for (x=0; ;x++)
        {
        printf(" Welchen Datensatz moechten Sie loeschen (0 zum Beenden)? \n");
        gets(eingabe);
        if (atoi(&eingabe[0]) == 0)        /* 0 beendet die Eingabe */
            {
            break;
            }
        groesse = (atoi (&eingabe[0]));
        x = groesse-1;
        printf(" Das Buch Nr. %i wirklich loeschen? J//N\n", groesse);  /* Sicherheitsabfrage */
        auswahl = getchar();
        switch (auswahl)
            {
            case 'J':
            case 'j':
                if (x == z) 
                    {
                    strcpy(buecher[x].titel,"\0");
                    break;
                    }
                while (x != z) 
                    {
                    buecher[x].inv_nr = buecher[groesse].inv_nr;
                    buecher[x].mwst = buecher[groesse].mwst;
                    buecher[x].preis = buecher[groesse].preis;
                    buecher[x].stck = buecher[groesse].stck;
                    strcpy(buecher[x].titel, buecher[groesse].titel);
                    x++;
                    groesse++;
                    }
            case 'n':
            case 'N':
                break;
            default: 
                printf(" Ungültige Taste");
                break;
            }
        }
    }
    

    Die Werte sind schon in der Struct, bzw. werden durch den Aufruf von Lesen() in die Struct gebracht. Vielen Dank im Voraus! 🙄



  • also du könntest das auch so machen:

    -neues Array mit der größe des Bücher Arrays -1 erzeugen
    -1. hälfte des Büchers Array rüberkopieren (also alle von 0-[Zu löschenden Eintrag)
    -alle Elemente nach dem zu löschenden Eintrag rüberkopieren
    -dann den Speicher von buecher freigeben und buecher auf das neue Array zeigen lassen

    BTW.
    noch einige Probleme/Fehler/Tipps zu deinem Programm:

    gets(eingabe);
    

    gets ist oberpfui, da es leicht zu Bufferoverflows führt, da keine Eingaben länge geprüft wird. Benutz am besten fgets (stdin als Dateihandle), da fgets die länge prüft. Da du aber eh die eingabe nach int umwandelst, kannst du auch direkt scanf nehmen.

    &eingabe[0]
    

    Da verstehe ich den Sinn nicht. Du erhälst ein char, da atoi aber ein char * haben will, trickst du da ein bisschen, da atoi aber bis zu einer 0 oder einem Zeichen liest, wo isdigit false ergibt, liest atoi dann eh über die Grenze des einen chars und geht doch eingabe komplett durch. Also solltest du das weglassen.

    "J//N"
    

    Bei einem / kannst du dir das 2. / sparen, dass brauchst du nur bei \, damit es keine Probleme mit Escape Seuqenzen gibt

    x++;
                    groesse++;
    

    Benutze lieber den Präfix ++ Operator, weil dieser idr. schneller oder zumindest gleichschnell wie der Postfix Operator ist

    (also ++x anstelle x++)

    [ Dieser Beitrag wurde am 22.10.2002 um 11:24 Uhr von kingruedi editiert. ]



  • Sicher ne gute Idee, aber die Grösse meiner Struct ist variabel.. da ich ja nicht von vorneherein weiss, ob da 2 oder 20 Bücher drinstehen sollen... 😞
    Sonst noch nen Tip?



  • Du redest immer von struct, meinst aber array.

    Eine Möglichkeit wär noch, in den struct ein boolsches Flag einzubauen, das auf true gesetzt wird, wenn der Datensatz gelöscht ist. Beim Neueinfügen suchst du dann ein gelöschtes und überschreibst es. Beim Anzeigen und Suchen übergehst du die gelöschten.

    struct Datensatz {
      unsigned geloescht:1;
      /* hier die bisherigen Daten */
      ...
    };
    

    Dazu gehört dann noch eine Aufräumen-Funktion, die genau das tut, was kingruedi vorgeschlagen hat, nämlich ein neues Array allozieren und alles was nicht gelöscht ist rüberzukopieren.



  • dann hälst du am besten eine Variable für die Arraygröße bereit. An deiner Stelle hätte ich eh eine doppelt verkettete Liste genommen anstelle eines Arrays, da Einfügen und Löschen dort schneller funktioniert (was bei einer DB ja sehr häufige Zugriffe sind).

    @Bashar

    unsigned lala:1;
    

    mittlerweile gibt es doch auch in C (seit C99) einen Bool Type



  • der kostet aber mehr Speicher.



  • sicher? Eigentlich sollte das doch Compiler abhängig sein 🙂



  • ein _Bool hat eine Adresse, also muß es mindestens so groß sein wie char



  • hast recht (wie immer 🙄 ;))


Anmelden zum Antworten