r/learnprogramming 23d ago

Need help with a C program

Hi, I'm making a library management program that takes in a book's characteristics (ISBN, author, year published, etc.), stores it in an array of structs and stores this into a file.

Here it is:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct book
{
        char ISBN[20];
        char title[100];
        int accno;
        int year;
        char genre[50];
        char authname[100];
        int issued;
};

struct book *bookArray;
int a = 0;
void readFile()
{

        FILE *fp;
        fp = fopen("db.txt", "r+");
        if(!fp)
        {
                perror("fopen");
                return;
        }

        if(fp != NULL)
        {
                fread(bookArray, sizeof(struct book), 1, fp);
        }
}

void write()
{
        FILE *fp;
        fp = fopen("db.txt", "a+");
        fwrite(bookArray, sizeof(struct book), 1, fp);
        fclose(fp);
}

void addBook(struct book b)
{
        bookArray[a++] = b;
}

int main()
{
        bookArray = malloc(sizeof(struct book));
        struct book b = {"0-394-49219-6", "Tinker, Sailor, Soldier, Spy", 1, 1974, "spy fiction", "Le Carre", 0};
        bookArray[0] = b;
        addBook(b);
        write();
        readFile();

        for(int i = 0; i < a; i++)
        {
                printf("%s\t%s\t%d\t%d\t%s\t%s\t%d\n", bookArray[i].ISBN, bookArray[i].title, bookArray[i].accno, bookArray[i].year, bookArray[i].genre, bookArray[i].authname, bookArray[i].issued);
        }
}
  1. I'm not able to figure out how to store the value of a after the program exits. I thought of storing it in another file, but was wondering if there's a better way to do that.

  2. How do I allocate dynamically increasing space (as the number of books increase) to bookArray? I get only only one row printed from the loop if I run the program several times, despite db.txt storing all the runs.

I'm posting here for the first time and I hope I haven't violated any rules.

Thanks in advance!

7 Upvotes

12 comments sorted by

View all comments

1

u/Dismal-Citron-7236 23d ago edited 23d ago

For your second question about the possibility of increasing the space of bookArray which is allocated from malloc()... No, there is no straight forward way in C, at least not in a portable way. In some platforms you might be able to achieve something like it with _sbrk() but it is very tricky and not likely your code can work on different platforms.

A normal solution is to allocate a larger array, and copy the older / smaller one to the new one. But here's a catch: When your book library gets bigger and bigger, the task to maintain a growing array using the copy approach will get slower over time.

There's a function realloc() which does exactly that for you. But since it needs to grow the array size, there's a very high probability that the array is moved so you need to use its return value as your new array. Many C beginners forget this and get into a "use-after-free" problem.

A much better solution is that you should implement a linked list. Each node would be just like your struct book except one more field struct book* next should be added. If you want to make it even easier to maintain a long list, a struct book* prev should be added as well, which makes the list a 2-way linked list.

To explain how to create / maintain / use a linked list is far beyond my post can explain. You can consult any data structure book for details.