#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BOOKS_FILE "books.dat"
#define MEMBERS_FILE "members.dat"
#define ISSUES_FILE "issues.dat"
#define MAX_TITLE 100
#define MAX_NAME 50
#define FINE_PER_DAY 2.0
#define MAX_DAYS 14
typedef struct {
int bookId;
char title[MAX_TITLE];
char author[MAX_NAME];
int totalCopies;
int availableCopies;
int isActive;
} Book;
typedef struct {
int memberId;
char name[MAX_NAME];
int booksIssued;
int isActive;
} Member;
typedef struct {
int issueId;
int bookId;
int memberId;
time_t issueDate;
time_t returnDate;
int isReturned;
double fine;
} IssueRecord;
// Utility: Get next ID from file
int getNextId(const char *filename, size_t recSize, size_t idOffset) {
FILE *fp = fopen(filename, "rb");
if (!fp) return 1;
int maxId = 0;
char buffer[256];
while (fread(buffer, recSize, 1, fp) == 1) {
int id = *(int*)(buffer + idOffset);
if (id > maxId) maxId = id;
}
fclose(fp);
return maxId + 1;
}
// ====== BOOK MANAGEMENT ======
void addBook() {
Book book;
book.bookId = getNextId(BOOKS_FILE, sizeof(Book), 0);
book.isActive = 1;
printf("\n--- Add New Book ---\n");
getchar();
printf("Title: ");
fgets(book.title, MAX_TITLE, stdin);
book.title[strcspn(book.title, "\n")] = '\0';
printf("Author: ");
fgets(book.author, MAX_NAME, stdin);
book.author[strcspn(book.author, "\n")] = '\0';
printf("Number of Copies: ");
scanf("%d", &book.totalCopies);
book.availableCopies = book.totalCopies;
FILE *fp = fopen(BOOKS_FILE, "ab");
fwrite(&book, sizeof(Book), 1, fp);
fclose(fp);
printf("Book added! ID: %d\n", book.bookId);
}
void searchBook() {
char query[MAX_TITLE];
getchar();
printf("Enter title or author to search: ");
fgets(query, MAX_TITLE, stdin);
query[strcspn(query, "\n")] = '\0';
FILE *fp = fopen(BOOKS_FILE, "rb");
if (!fp) { printf("No books in library.\n"); return; }
Book book;
int found = 0;
printf("\n%-5s %-40s %-25s %-10s %-10s\n", "ID", "Title", "Author", "Total", "Available");
printf("------------------------------------------------------------------------------------\n");
while (fread(&book, sizeof(Book), 1, fp) == 1) {
if (book.isActive && (strstr(book.title, query) || strstr(book.author, query))) {
printf("%-5d %-40s %-25s %-10d %-10d\n",
book.bookId, book.title, book.author,
book.totalCopies, book.availableCopies);
found++;
}
}
if (!found) printf("No books found matching '%s'\n", query);
fclose(fp);
}
void displayBooks() {
FILE *fp = fopen(BOOKS_FILE, "rb");
if (!fp) { printf("No books found.\n"); return; }
Book book;
printf("\n%-5s %-40s %-25s %-6s %-6s\n", "ID", "Title", "Author", "Total", "Avail");
printf("------------------------------------------------------------------------------------\n");
while (fread(&book, sizeof(Book), 1, fp) == 1) {
if (book.isActive) {
printf("%-5d %-40s %-25s %-6d %-6d\n",
book.bookId, book.title, book.author,
book.totalCopies, book.availableCopies);
}
}
fclose(fp);
}
// ====== MEMBER MANAGEMENT ======
void addMember() {
Member member;
member.memberId = getNextId(MEMBERS_FILE, sizeof(Member), 0);
member.booksIssued = 0;
member.isActive = 1;
getchar();
printf("\n--- Register New Member ---\n");
printf("Name: ");
fgets(member.name, MAX_NAME, stdin);
member.name[strcspn(member.name, "\n")] = '\0';
FILE *fp = fopen(MEMBERS_FILE, "ab");
fwrite(&member, sizeof(Member), 1, fp);
fclose(fp);
printf("Member registered! ID: %d\n", member.memberId);
}
// ====== ISSUE/RETURN ======
void issueBook() {
int bookId, memberId;
printf("\nEnter Book ID: ");
scanf("%d", &bookId);
printf("Enter Member ID: ");
scanf("%d", &memberId);
// Find and validate book
FILE *fp = fopen(BOOKS_FILE, "rb+");
if (!fp) { printf("Error!\n"); return; }
Book book;
int bookFound = 0;
while (fread(&book, sizeof(Book), 1, fp) == 1) {
if (book.bookId == bookId && book.isActive) {
if (book.availableCopies <= 0) {
printf("No copies available!\n");
fclose(fp);
return;
}
book.availableCopies--;
fseek(fp, -(long)sizeof(Book), SEEK_CUR);
fwrite(&book, sizeof(Book), 1, fp);
bookFound = 1;
break;
}
}
fclose(fp);
if (!bookFound) { printf("Book not found!\n"); return; }
// Create issue record
IssueRecord issue;
issue.issueId = getNextId(ISSUES_FILE, sizeof(IssueRecord), 0);
issue.bookId = bookId;
issue.memberId = memberId;
issue.issueDate = time(NULL);
issue.returnDate = 0;
issue.isReturned = 0;
issue.fine = 0;
fp = fopen(ISSUES_FILE, "ab");
fwrite(&issue, sizeof(IssueRecord), 1, fp);
fclose(fp);
char dateStr[30];
strftime(dateStr, 30, "%d-%m-%Y", localtime(&issue.issueDate));
printf("Book Issued Successfully!\n");
printf("Issue ID: %d | Date: %s | Due in %d days\n",
issue.issueId, dateStr, MAX_DAYS);
}
void returnBook() {
int issueId;
printf("\nEnter Issue ID: ");
scanf("%d", &issueId);
FILE *fp = fopen(ISSUES_FILE, "rb+");
if (!fp) { printf("No records!\n"); return; }
IssueRecord issue;
int found = 0;
while (fread(&issue, sizeof(IssueRecord), 1, fp) == 1) {
if (issue.issueId == issueId && !issue.isReturned) {
issue.returnDate = time(NULL);
issue.isReturned = 1;
// Calculate fine
double days = difftime(issue.returnDate, issue.issueDate) / 86400.0;
if (days > MAX_DAYS) {
issue.fine = (days - MAX_DAYS) * FINE_PER_DAY;
}
fseek(fp, -(long)sizeof(IssueRecord), SEEK_CUR);
fwrite(&issue, sizeof(IssueRecord), 1, fp);
found = 1;
printf("Book Returned Successfully!\n");
printf("Days kept: %.0f\n", days);
if (issue.fine > 0)
printf("Fine: Rs. %.2f (%.0f days overdue)\n", issue.fine, days - MAX_DAYS);
else
printf("No fine. Returned on time!\n");
break;
}
}
fclose(fp);
if (!found) printf("Issue record not found or already returned.\n");
// Increment available copies
if (found) {
fp = fopen(BOOKS_FILE, "rb+");
Book book;
while (fread(&book, sizeof(Book), 1, fp) == 1) {
if (book.bookId == issue.bookId) {
book.availableCopies++;
fseek(fp, -(long)sizeof(Book), SEEK_CUR);
fwrite(&book, sizeof(Book), 1, fp);
break;
}
}
fclose(fp);
}
}
int main() {
int choice;
while (1) {
printf("\n=========================================\n");
printf(" LIBRARY MANAGEMENT SYSTEM\n");
printf("=========================================\n");
printf("1. Add Book\n");
printf("2. Search Book\n");
printf("3. Display All Books\n");
printf("4. Register Member\n");
printf("5. Issue Book\n");
printf("6. Return Book\n");
printf("7. Exit\n");
printf("=========================================\n");
printf("Choice: ");
scanf("%d", &choice);
switch (choice) {
case 1: addBook(); break;
case 2: searchBook(); break;
case 3: displayBooks(); break;
case 4: addMember(); break;
case 5: issueBook(); break;
case 6: returnBook(); break;
case 7: printf("Goodbye!\n"); return 0;
default: printf("Invalid choice!\n");
}
}
}