A complete CRUD application for a library database, built in C using binary file I/O as the persistence layer. Includes both a console (terminal) interface and a GTK3 graphical interface.
| Table | Key Fields |
|---|---|
| Authors | author_id, name, bio |
| Publishers | publisher_id, name, address, contact_info |
| Books | book_id, title, author_id(FK), publisher_id(FK), isbn, genre, year, copies, shelf |
| Members | member_id, name, address, phone, email, date_joined, membership_status |
| Staff | staff_id, name, role, email, phone |
| Borrowings | borrowing_id, book_id(FK), member_id(FK), borrow_date, due_date, return_date, staff_id(FK) |
| Fines | fine_id, borrowing_id(FK), amount, paid, date_paid |
Data is stored as binary flat files in the data/ directory (one .dat
file per table). Each file begins with a 4-byte next_id counter.
library_system/
├── include/
│ ├── models.h ← C structs for all 7 tables
│ ├── db.h ← CRUD function declarations
│ ├── console_ui.h ← Console menu declarations
│ └── gui_ui.h ← GTK GUI declarations
├── src/
│ ├── db.c ← File I/O CRUD (shared by both apps)
│ ├── console_ui.c ← Interactive terminal menus
│ ├── gui_ui.c ← GTK3 windowed interface
│ ├── main_console.c ← Console entry point
│ └── main_gui.c ← GUI entry point
├── data/ ← Auto-created at first run
└── Makefile
- GCC (any recent version)
- No external dependencies
- GTK3 development libraries
Install GTK3:
# Ubuntu / Debian
sudo apt install libgtk-3-dev
# Fedora / RHEL
sudo dnf install gtk3-devel
# macOS (Homebrew)
brew install gtk+3
# Windows (MSYS2)
pacman -S mingw-w64-x86_64-gtk3cd library_system
# Build console app only
make console
# Build GUI app only (requires GTK3)
make gui
# Build both
make all
# Run console app
./library_console
# Run GUI app
./library_guiThe console app presents a numbered menu system:
──────────────────────────────────────────────────
LIBRARY MANAGEMENT SYSTEM — MAIN MENU
──────────────────────────────────────────────────
1. Authors
2. Publishers
3. Books
4. Members
5. Staff
6. Borrowings
7. Fines
0. Exit
Each sub-menu offers:
- Add a new record
- View / Search records
- Update an existing record
- Delete a record (soft-delete — data stays in file, marked inactive)
- Return Book — automatically decrements copy count and calculates overdue fine (1.0 per day late)
- Overdue List — shows all unreturned borrowings past due date
- By Member — shows all borrowings for a specific member
- Pay Fine — marks fine as paid, records today's date
The GTK3 GUI has a sidebar with one button per table. Click a table name to switch to its panel, which shows a live grid of records plus action buttons:
| Button | Action |
|---|---|
| ➕ Add | Opens a form dialog to insert a new record |
| ✏️ Edit | Opens a pre-filled form to update the selected row |
| 🗑 Delete | Confirms then soft-deletes the selected record |
| ↩ Return Book | (Borrowings) processes a return + auto-fine |
| 💳 Mark Paid | (Fines) marks a fine as paid |
Each .dat file starts with a 4-byte integer (the next_id counter).
Records are appended sequentially. Deletion sets the active flag to 0
(soft delete); queries skip inactive records.
db.c uses a C macro to generate all five CRUD functions for each table,
keeping the codebase DRY. Only tables with extra operations (Borrowings,
Fines) have additional hand-written functions.
The console and GUI both validate that referenced IDs exist before inserting a Borrowing. Copy counts are adjusted automatically.
When a book is returned late, borrowing_return_book() calculates
(return_date − due_date) in days and inserts a Fine record automatically.
- Connect to real MySQL: replace
db.cfunctions withmysql.hcalls (the rest of the code stays identical). - Add search: extend
db.h/db.cwith a*_search_by_name()function and hook it into the UI. - Reports: add a Reports menu that aggregates borrowing stats, top books, overdue counts, etc.
- Authentication: add a login screen in the GUI before showing the main window.