Thread: delete record from random access binary file

  1. #1
    Registered User
    Join Date
    Jun 2017
    Posts
    88

    delete record from random access binary file

    Is it possible to completely delete a record from a random access binary file without making an entirely new file?

    This is the code I've been lazily working on for a couple weeks:
    Code:
    #include <stdio.h>
    #include <string.h>
     
    typedef struct person {
        char lastName[15];
        char firstName[15];
        char age[4];
    } Person;
     
    void blank100();
    void tenEntry();
    void printTen();
    void updateRecord();
    void deleteRecord();
     
    int main(void) {
     
        blank100();
        tenEntry();
        printTen();
        updateRecord();
        printTen();
        deleteRecord();
        printTen();
    }
     
    // Creates 100 blank entries
    void blank100() {
        
        FILE* wfPtr;
        if ((wfPtr = fopen("nameage.dat", "wb")) == NULL) {
            puts("Error opening nameage.dat for writing");
            return;
        }
     
        Person blankPerson = { "", "", "0" };
     
        for (int i0 = 0; i0 < 100; ++i0) {
            fwrite(&blankPerson, sizeof(Person), 1, wfPtr);
        }
        fclose(wfPtr);
    }
     
    // Fills ten entries
    void tenEntry() {
     
        FILE* wfPtr;
        if ((wfPtr = fopen("nameage.dat", "wb")) == NULL) {
            puts("Error opening nameage.dat for writing");
            return;
        }
     
        Person p0 = { "Anderly", "Charley", "54" };
        Person p1 = { "Schultz", "Gilberto", "67" };
        Person p2 = { "Cuevas", "Abbigail", "34" };
        Person p3 = { "Rhodes", "Gregory", "83" };
        Person p4 = { "Taylor", "Giovanna", "78" };
        Person p5 = { "Glenn", "Kole", "54" };
        Person p6 = { "Reilly", "Dennis", "41" };
        Person p7 = { "Morrix", "Shannon", "27" };
        Person p8 = { "Herman", "Mekhi", "84" };
        Person p9 = { "Beltran", "Damari", "30" };
     
        fwrite(&p0, sizeof(Person), 1, wfPtr);
        fwrite(&p1, sizeof(Person), 1, wfPtr);
        fwrite(&p2, sizeof(Person), 1, wfPtr);
        fwrite(&p3, sizeof(Person), 1, wfPtr);
        fwrite(&p4, sizeof(Person), 1, wfPtr);
        fwrite(&p5, sizeof(Person), 1, wfPtr);
        fwrite(&p6, sizeof(Person), 1, wfPtr);
        fwrite(&p7, sizeof(Person), 1, wfPtr);
        fwrite(&p8, sizeof(Person), 1, wfPtr);
        fwrite(&p9, sizeof(Person), 1, wfPtr);
     
        fclose(wfPtr);
    }
     
    // Prints the first ten entries
    void printTen() {
     
        FILE* rfPtr;
        if ((rfPtr = fopen("nameage.dat", "rb")) == NULL) {
            puts("Error opening nameage.dat for reading");
            return;
        }
     
        Person toScreen = { "", "", "0" };
     
        for (int i0 = 0; fread(&toScreen, sizeof(Person), 1, rfPtr) && i0 < 10; ++i0) {
            printf("%s, %s, %s\n", toScreen.lastName, toScreen.firstName, toScreen.age);
        }
        puts("");
        fclose(rfPtr);
    }
     
    // updates one record with a new age value
    void updateRecord() {
        
        FILE* rpfPtr;
        if ((rpfPtr = fopen("nameage.dat", "rb+")) == NULL) {
            puts("Error opening nameage.dat r+");
        }
     
        Person newData = { "", "", "0" };
        printf("Enter existing lastName, firstName, newAge: ");
        char line[50];
        fgets(line, 50, stdin);
        char* token = strtok(line, ", \n");
        strcpy(newData.lastName, token);
        token = strtok(NULL, ", \n");
        strcpy(newData.firstName, token);
        token = strtok(NULL, ", \n");
        strcpy(newData.age, token);
        
        Person search = { "", "", "0" };
        while (fread(&search, sizeof(Person), 1, rpfPtr) && strcmp(search.lastName, newData.lastName)) {
            
        }
        if (strcmp(search.lastName, newData.lastName) == 0) {
            fseek(rpfPtr, -1 * (int)sizeof(Person), SEEK_CUR);
            fwrite(&newData, sizeof(Person), 1, rpfPtr);
        }
        else {
            puts("Record not found.\n");
        }
     
        fclose(rpfPtr);
    }
     
    // deletes one record
    void deleteRecord() {
        FILE* fPtr;
        if ((fPtr = fopen("nameage.dat", "rb+")) == NULL) {
            puts("Error opening nameage.dat r+");
        }
     
        Person userEntry = { "", "", "0" };
        printf("Delete existing lastName, firstName, age: ");
        char line[50];
        fgets(line, 50, stdin);
        char* token = strtok(line, ", \n");
        strcpy(userEntry.lastName, token);
        token = strtok(NULL, ", \n");
        strcpy(userEntry.firstName, token);
        token = strtok(NULL, ", \n");
        strcpy(userEntry.age, token);
     
        Person search = { "", "", "0" };
        while (fread(&search, sizeof(Person), 1, fPtr) && strcmp(search.lastName, userEntry.lastName)) {
     
        }
        if (strcmp(search.lastName, userEntry.lastName) == 0) {
            fseek(fPtr, -1 * (int)sizeof(Person), SEEK_CUR);
            Person blank = { "", "", "" };
            fwrite(&blank, sizeof(Person), 1, fPtr);
        }
        else {
            puts("Record not found.\n");
        }
     
        fclose(fPtr);
    }
    Output:
    Code:
    Anderly, Charley, 54
    Schultz, Gilberto, 67
    Cuevas, Abbigail, 34
    Rhodes, Gregory, 83
    Taylor, Giovanna, 78
    Glenn, Kole, 54
    Reilly, Dennis, 41
    Morrix, Shannon, 27
    Herman, Mekhi, 84
    Beltran, Damari, 30
    
    Enter existing lastName, firstName, newAge: Rhodes, Jeff, 44
    Anderly, Charley, 54
    Schultz, Gilberto, 67
    Cuevas, Abbigail, 34
    Rhodes, Jeff, 44
    Taylor, Giovanna, 78
    Glenn, Kole, 54
    Reilly, Dennis, 41
    Morrix, Shannon, 27
    Herman, Mekhi, 84
    Beltran, Damari, 30
    
    Delete existing lastName, firstName, age: Rhodes, Abe, 3
    Anderly, Charley, 54
    Schultz, Gilberto, 67
    Cuevas, Abbigail, 34
    , ,
    Taylor, Giovanna, 78
    Glenn, Kole, 54
    Reilly, Dennis, 41
    Morrix, Shannon, 27
    Herman, Mekhi, 84
    Beltran, Damari, 30
    It is the , , that bothers me a little. It comes from saving the blank record { "", "", "" } into the record I want to delete. I suppose I could modify the printing of records.
    Last edited by jack jordan; 11-06-2017 at 02:03 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    37,530
    > I suppose I could modify the printing of records.
    That's pretty much what you have to do.
    You make a specific instance of your record (say all the strings begin with \0) which means 'deleted record' and then code around it.

    The only way to physically remove the record from the file is to copy all the records you want to keep to another file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help: Updating Record In Random Access File
    By teensicle in forum C Programming
    Replies: 1
    Last Post: 11-06-2014, 12:01 AM
  2. Binary file - delete record issue
    By ulti-killer in forum C Programming
    Replies: 1
    Last Post: 12-03-2012, 11:29 AM
  3. Specif Record Read error in random access files.
    By infantheartlyje in forum C++ Programming
    Replies: 0
    Last Post: 10-31-2011, 01:41 AM
  4. Update Record & Delete Record in File.
    By unsafe_pilot1 in forum C Programming
    Replies: 13
    Last Post: 05-18-2008, 07:22 AM
  5. Delete a binary record
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 07-01-2002, 02:07 AM

Tags for this Thread