loeschen eines struct aus einer binaere datei



  • hallo leute, habe ein pr geschrieben was Personen in eine binaere datei speicher und wieder herausliest und jetzt moechte ich eine person wieder gerne loeschen aber ich weiß nicht wie ich anfangen soll. so sieht mein pr aus!!
    mfg

    struct Datum{

    int t;
    int m;
    int j;
    };

    struct Person{
    char name[50];
    struct Datum gebdat;
    };

    int input(int u, int o, char type[10]){

    int z;
    int x;
    int jahr;

    if(strcmp(type,"Jahr") == 0){
    do{
    printf("Bitte geben Sie ein Jahr ein <1800-2008>! ");
    scanf("%d", &z);
    jahr=z;
    } while ((z<u) || (z>o));
    } else if (strcmp(type,"Monat") == 0){
    do{
    printf("Bitte geben Sie einen Monat ein <1-12>! ");
    scanf("%d", &z);
    if (z == 2){
    x=z;
    }
    if ((z == 1) ||
    (z == 3) ||
    (z == 5) ||
    (z == 7) ||
    (z == 😎 ||
    (z == 10) ||
    (z == 12)){
    x=z;
    }
    } while ((z<u) || (z>o));
    } else if(strcmp(type,"Tag") == 0){
    if (x == 2){
    if (((jahr % 4 == 0 && jahr % 100 != 0) || jahr % 400 == 0) && z == 2){
    printf("Es ist ein Schaltjahr, dieser Monat hat 29 Tage!\n");
    o=29;
    } else {
    printf("Es ist kein Schaltjahr, dieser Monat hat 28 Tage!\n");
    o=28;
    }
    } else if ((x == 1) ||
    (x == 3) ||
    (x == 5) ||
    (x == 7) ||
    (x == 😎 ||
    (x == 10) ||
    (x == 12)){
    printf("Dieser Monat hat 31 Tage!\n");
    o=31;
    } else {
    printf("Dieser Monat hat 30 Tage!\n");
    o=30;
    }
    do{
    printf("Bitte geben Sie einen Tag ein <1-%d>! ", o);
    scanf("%d", &z);
    } while ((z<u) || (z>o));
    printf("Person wurde erfolgreich erstellt!");
    }
    return z;
    }

    int PersNum(int persz){ //Eingabe der Personenzahl

    int z;

    printf("Bitte gebe Sie eine Zahl ein <1-%d>: ", persz);
    scanf("%d", &z);

    return z;
    }

    int main(int argc, char *argv[]){

    FILE *fp;
    int persz = 0; //Anzahl der Personen
    struct Person p;
    int eingabe;
    int z;

    fp = fopen("pers.dat","wb");
    fclose(fp);
    fp=fopen("pers.dat","a+b");

    if (fp != NULL){

    do{
    do{
    printf("\n\n1-> Neue Person erstellen!\n");
    printf("2-> Eingeben einer Nr. -> Ausgabe einer Person!\n");
    printf("3-> Eingeben einer Nr. -> Loeschen einer Person!\n");
    printf("4-> Eingeben einer Nr. -> Updaten einre Person!\n");
    printf("5-> Sortieren nach Namen!\n"); //bis 24.1.
    printf("6-> Sortieren nach Geburtsdatum!\n");
    printf("7-> Sortieren nach Namen und Geburtsdatum!\n");
    printf("8-> Beenden\n");
    scanf("%d", &eingabe);
    } while((eingabe<1) || (eingabe>8));

    system("cls");

    switch (eingabe) {

    case 1:
    printf("Bitte geben Sie einen Namen ein! ");
    fflush(stdin);
    gets(p.name);
    p.gebdat.j=input(1800,2008,"Jahr");
    p.gebdat.m=input(1,12,"Monat");
    p.gebdat.t=input(1,31,"Tag");
    fwrite(&p,sizeof(p),1,fp);
    persz++;
    break;

    case 2:
    if (persz == 0){
    printf("Es sind keiner Personen vorhanden!\n");
    } else {
    z = PersNum(persz);
    fseek(fp,(z-1)*sizeof(p),SEEK_SET);
    fread(&p,sizeof(p),1,fp);
    puts(p.name);
    printf("%d.%d.%d\n",p.gebdat.t,p.gebdat.m,p.gebdat.j);
    }
    break;
    case 3: //Loeschen
    break;

    case 4: //Update
    break;
    case 5: //Alle ausgeben sortiert nach Namen
    break;
    case 6: //Alle ausgeben sortiert nach Geburtsdatum
    break;
    case 7: //Alle ausgeben sortiert nach Namen und Geburtsdatum
    break;
    }

    } while(eingabe != 8);
    fclose(fp);
    } else {
    printf("ERROR!");
    }

    system("PAUSE");
    return 0;
    }



  • kennst du c/c++ tags (cpp-tags) ?

    damit kannst du quelltext hevorheben.

    das hier:
    struct Person{
    char name[50];
    struct Datum gebdat;
    };

    sieht mit tags dann so aus:

    struct Person{
    char name[50];
    struct Datum gebdat;
    };
    

    🙂

    zu thema löchen einer struktur:
    das einfachste ist, wenn du den inhalt von name, oder einfach nur das erste zeichen( name[0] ) auf null setzt.
    der name hat dann keinen inhalt und beim einlesen der datei zeigst du nur die namen mit inhalt an. damit ist die struktur quasi gelöscht.



  • Was aber dazu führt, dass du "Leichen" in deiner Datei hast, die die
    Größe dann unnötig aufblähen.

    Wie wäre es mit folgendem Vorschlag:

    Du möchtest den i-ten Eintrag löschen. Dann überschreibst du ihn mit
    dem letzten und löscht den letzten aus der Datei?

    Gruß mcr



  • mcr schrieb:

    Was aber dazu führt, dass du "Leichen" in deiner Datei hast, die die
    Größe dann unnötig aufblähen.

    man könnte auch den speicherplatz der gelöschten einträge zum einfügen neuer einträge wiederverwenden. so wird die datei nur so gross wie die maximale anzahl an elementen, die jemals darin gewesen sind.
    🙂



  • der vorschlag von mcr gefällt mir, nur hab ich jetzt das problem einen einen namen mit gebdat zu kopieren, also nach vorne zu verschieben!

    ich hab so probiert aber leider funktioniert es nicht!

    for(i=z;i<persz;i++){
    fseek(fp,sizeof(p)(i+1),SEEK_SET);
    fread(&p,sizeof(p),1,fp);
    fseek(fp,sizeof(p)
    (i),SEEK_SET);
    fwrite(&p,sizeof(p)*(i+1),1,fp);
    }

    mfg



  • so^^ ist das doof
    mach' dir besser schreib- und lesefunktionen für einen kompletten datensatz (die wirst du sowieso brauchen) und dann benutze die auch für deine kopieroperation.
    🙂


Log in to reply