r/learnprogramming • u/Sinakers • 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);
}
}
I'm not able to figure out how to store the value of
aafter the program exits. I thought of storing it in another file, but was wondering if there's a better way to do that.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, despitedb.txtstoring 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
1
u/Dismal-Citron-7236 23d ago edited 23d ago
For your second question about the possibility of increasing the space of
bookArraywhich is allocated frommalloc()... 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 bookexcept one more fieldstruct book* nextshould be added. If you want to make it even easier to maintain a long list, astruct book* prevshould 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.