0

I'm trying to design a book management system in c. In this piece of code, I'm implementing the deleting function of a struct array, but it doesn't delete it. First I tried to not use the fread and fwrite functions for binary file, in order to see if the deleting algorithm was correct. When I try to add the fread and fwrite function it doesn't work. Can anyone help me figure this out? Thanks

do
{
    printf("Enter the book title: ");
    gets(deleted_book.title);
    fflush(stdin);
    fp = fopen("book.dat", "rb");
    for(i = 0; i < cont; i++)
    {
        fread(&book[i], sizeof(struct book_information), 1, fp);
        res_deleted = strcmp(deleted_book.title, book[i].title);
        reached_index = i;
        if(res_deleted == 0)
        {
            for(i = reached_index; i < cont; i++)
            {
                true_ = 1;
                book[i] = book[i+1];
            }
            cont--;
        }
    }
    fclose(fp);
    if(true_ == 0)
    {
        printf("There is no book with that title \n");
    }
}
while(true_ == 0);
  • 3
    Never ***ever*** use `gets`. It's so [dangerous](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used) it have been removed from the C standard. Use e.g. [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead. – Some programmer dude Oct 31 '20 at 02:15
  • Also, passing an input-only stream (like `stdin`) to `fflush` is specified to be *undefined behavior*. One system adds it as a non-portable extension, which means you should try to avoid it at all cost. – Some programmer dude Oct 31 '20 at 02:15
  • 5
    Lastly about your problem: The simplest way to "delete" a record from a file, is to read the file from beginning to the end, copying all data to a second temporary file, *except* the data you want to remove. Then rename the temporary file as the original file. – Some programmer dude Oct 31 '20 at 02:17
  • And as a more efficient option, if the size of the structs is known and fixed, you can skip to the last item, read its data, then skip to the item to delete, write over it, and shrink the file. – Tordek Oct 31 '20 at 02:19
  • 1
    The 'move the last entry to replace the deleted entry' trick only works if the entries are not in a specific order. Another technique writes zeros over the deleted entry, so when it is read (with `fread()` or equivalent), the data is identifiable as "invalid". It is possible, but expensive, to 'shift' the data down the file, overwriting the deleted record with those that follow, and then truncating. The POSIX function for truncating a file is [`ftruncate()`](https://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html), which takes an open file descriptor (not a file stream). – Jonathan Leffler Oct 31 '20 at 03:40

0 Answers0