【C语言】图书管理系统(文件存储版)丨源码+详解
一、系统介绍
这是一个基于C语言开发的终端图书管理系统,采用链表数据结构+二进制文件存储技术实现。系统具有以下特点:
- 双角色系统:管理员(管理图书)和读者(借阅/归还)
- 完整功能:图书添加、搜索、借阅、归还、显示等功能
- 数据持久化:所有图书信息保存在文件中,重启不丢失
- 健壮性设计:完善的输入验证和错误处理
二、系统完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> /* 宏定义 */ #define MAX_NAME 50 // 名称最大长度 #define MAX_ID 20 // ID最大长度 #if defined(_WIN32) #define CLEAR_SCREEN system("cls") // Windows清屏 #else #define CLEAR_SCREEN system("clear") // Linux/Mac清屏 #endif /* 数据结构 */ // 图书结构 typedef struct Book { char isbn[MAX_ID]; // ISBN号 char title[MAX_NAME]; // 书名 char author[MAX_NAME]; // 作者 int total_count; // 总数量 int available_count; // 可借数量 struct Book *next; // 链表指针 } Book; // 借阅记录 typedef struct BorrowRecord { char user_id[MAX_ID]; // 借阅者ID char book_isbn[MAX_ID]; // 图书ISBN time_t borrow_date; // 借书日期(时间戳) time_t return_date; // 还书日期 struct BorrowRecord *next; // 链表指针 } BorrowRecord; /* 全局变量 */ Book *book_list = NULL; // 图书链表头指针 BorrowRecord *borrow_list = NULL; // 借阅记录链表头指针 /************************************ * 工具函数:清空输入缓冲区 ************************************/ void clear_input_buffer() { int c; while ((c = getchar()) != '\n' && c != EOF); } /************************************ * 数据加载:从文件读取图书数据 ************************************/ void load_books() { FILE *fp = fopen("books.dat", "rb"); if (fp == NULL) return; Book book_temp; while (fread(&book_temp, sizeof(Book), 1, fp) == 1) { Book *new_book = (Book*)malloc(sizeof(Book)); *new_book = book_temp; new_book->next = book_list; book_list = new_book; } fclose(fp); } /************************************ * 数据保存:将当前图书数据写入文件 ************************************/ void save_books() { FILE *fp = fopen("books.dat", "wb"); if (fp == NULL) { printf("错误:无法保存数据!\n"); return; } Book *current = book_list; while (current != NULL) { fwrite(current, sizeof(Book), 1, fp); current = current->next; } fclose(fp); } /************************************ * 功能:添加新书(管理员权限) ************************************/ void add_book() { CLEAR_SCREEN; printf("\n======== 添加新书 ========\n"); Book *new_book = (Book*)malloc(sizeof(Book)); // 输入ISBN并查重 printf("ISBN: "); scanf("%19s", new_book->isbn); clear_input_buffer(); Book *current = book_list; while (current != NULL) { if (strcmp(current->isbn, new_book->isbn) == 0) { printf("错误:ISBN已存在!\n"); free(new_book); return; } current = current->next; } // 输入其他信息 printf("书名: "); fgets(new_book->title, MAX_NAME, stdin); new_book->title[strcspn(new_book->title, "\n")] = '\0'; // 去掉换行符 printf("作者: "); fgets(new_book->author, MAX_NAME, stdin); new_book->author[strcspn(new_book->author, "\n")] = '\0'; printf("总数量: "); scanf("%d", &new_book->total_count); new_book->available_count = new_book->total_count; clear_input_buffer(); // 插入链表 new_book->next = book_list; book_list = new_book; printf("\n图书《%s》添加成功!\n", new_book->title); save_books(); // 保存到文件 } /************************************ * 功能:按关键字搜索图书(支持模糊搜索) ************************************/ void search_book() { CLEAR_SCREEN; printf("\n======== 图书搜索 ========\n"); char keyword[MAX_NAME]; printf("输入ISBN/书名/作者关键字: "); fgets(keyword, MAX_NAME, stdin); keyword[strcspn(keyword, "\n")] = '\0'; // 去掉换行符 if (strlen(keyword) == 0) { printf("搜索内容不能为空!\n"); return; } Book *current = book_list; int found = 0; while (current != NULL) { // 检查ISBN、书名、作者是否匹配 if (strstr(current->isbn, keyword) != NULL || strstr(current->title, keyword) != NULL || strstr(current->author, keyword) != NULL) { printf("\n--------------------"); printf("\nISBN: %s\n书名: %s\n作者: %s\n数量: %d/%d\n", current->isbn, current->title, current->author, current->available_count, current->total_count); found = 1; } current = current->next; } if (!found) { printf("未找到匹配的图书!\n"); } } /************************************ * 功能:借阅图书(读者权限) ************************************/ void borrow_book(char *user_id) { CLEAR_SCREEN; printf("\n======== 借阅图书 ========\n"); char isbn[MAX_ID]; printf("输入要借阅的图书ISBN: "); scanf("%19s", isbn); clear_input_buffer(); // 查找图书 Book *book = book_list; while (book != NULL) { if (strcmp(book->isbn, isbn) == 0) break; book = book->next; } // 检查图书状态 if (book == NULL) { printf("错误:找不到该图书!\n"); return; } else if (book->available_count <= 0) { printf("错误:该书已全部借出!\n"); return; } // 创建借阅记录 BorrowRecord *record = (BorrowRecord*)malloc(sizeof(BorrowRecord)); strcpy(record->user_id, user_id); strcpy(record->book_isbn, isbn); record->borrow_date = time(NULL); // 当前时间 record->return_date = 0; // 0表示未归还 // 更新图书库存 book->available_count--; // 添加记录到链表 record->next = borrow_list; borrow_list = record; printf("\n借阅成功!\n"); printf("归还期限: 30天内\n"); printf("借阅时间: %s", ctime(&record->borrow_date)); save_books(); // 保存库存变更 } /************************************ * 功能:归还图书(读者权限) ************************************/ void return_book(char *user_id) { CLEAR_SCREEN; printf("\n======== 归还图书 ========\n"); char isbn[MAX_ID]; printf("输入要归还的图书ISBN: "); scanf("%19s", isbn); clear_input_buffer(); // 查找借阅记录(未归还状态) BorrowRecord *prev = NULL; BorrowRecord *current = borrow_list; int found = 0; while (current != NULL) { if (strcmp(current->user_id, user_id) == 0 && strcmp(current->book_isbn, isbn) == 0 && current->return_date == 0) { found = 1; // 更新图书库存 Book *book = book_list; while (book != NULL) { if (strcmp(book->isbn, isbn) == 0) { book->available_count++; break; } book = book->next; } // 更新归还日期 current->return_date = time(NULL); printf("\n归还成功!\n"); printf("归还时间: %s", ctime(¤t->return_date)); save_books(); return; } prev = current; current = current->next; } if (!found) { printf("错误:未找到借阅记录或已归还!\n"); } } /************************************ * 功能:显示所有图书信息 ************************************/ void display_all_books() { CLEAR_SCREEN; printf("\n======== 所有图书 ========\n"); printf("%-15s %-25s %-20s %-10s\n", "ISBN", "书名", "作者", "库存(可借/总数)"); Book *current = book_list; while (current != NULL) { printf("%-15s %-25s %-20s %d/%d\n", current->isbn, current->title, current->author, current->available_count, current->total_count); current = current->next; } } /************************************ * 管理员菜单 ************************************/ void admin_menu() { int choice; while (1) { CLEAR_SCREEN; printf("\n======= 管理员菜单 =======\n"); printf("1. 添加图书\n"); printf("2. 搜索图书\n"); printf("3. 查看所有图书\n"); printf("0. 退出\n"); printf("请选择操作: "); scanf("%d", &choice); clear_input_buffer(); switch (choice) { case 1: add_book(); break; case 2: search_book(); break; case 3: display_all_books(); break; case 0: return; default: printf("无效选择!\n"); } printf("\n按回车键继续..."); getchar(); } } /************************************ * 读者菜单 ************************************/ void reader_menu(char *user_id) { int choice; while (1) { CLEAR_SCREEN; printf("\n======= 读者菜单 =======\n"); printf("读者ID: %s\n", user_id); printf("1. 借阅图书\n"); printf("2. 归还图书\n"); printf("3. 搜索图书\n"); printf("4. 查看所有图书\n"); printf("0. 退出\n"); printf("请选择操作: "); scanf("%d", &choice); clear_input_buffer(); switch (choice) { case 1: borrow_book(user_id); break; case 2: return_book(user_id); break; case 3: search_book(); break; case 4: display_all_books(); break; case 0: return; default: printf("无效选择!\n"); } printf("\n按回车键继续..."); getchar(); } } /************************************ * 主函数 ************************************/ int main() { load_books(); // 启动时加载图书数据 while (1) { CLEAR_SCREEN; printf("======= 图书管理系统 =======\n"); printf("1. 管理员登录\n"); printf("2. 读者登录\n"); printf("0. 退出系统\n"); printf("请选择: "); int option; if (scanf("%d", &option) != 1) { clear_input_buffer(); continue; } clear_input_buffer(); switch (option) { case 1: admin_menu(); break; case 2: { char user_id[MAX_ID]; printf("请输入读者ID: "); fgets(user_id, MAX_ID, stdin); user_id[strcspn(user_id, "\n")] = '\0'; reader_menu(user_id); break; } case 0: { // 程序退出前保存数据 save_books(); printf("感谢使用,再见!\n"); return 0; } default: printf("无效选择!\n"); } } }
三、系统功能详解
1. 主要功能模块
| 功能模块 | 描述 | 访问权限 |
|---|---|---|
| 图书添加 | 添加新书到系统,包含ISBN、书名、作者等信息 | 管理员 |
| 图书搜索 | 通过ISBN、书名或作者关键字查找图书 | 所有用户 |
| 借阅管理 | 借阅图书并自动记录借阅时间和读者ID | 读者 |
| 归还管理 | 归还已借阅图书并更新库存 | 读者 |
| 图书显示 | 以表格形式展示所有图书信息 | 所有用户 |
2. 数据结构设计

3. 文件存储机制
系统使用二进制文件books.dat保存所有图书数据,采用以下技术:
- 序列化存储:直接将内存中的结构体写入文件
- 链表遍历:通过
fwrite逐个节点写入文件 - 读取加载:启动时重新构建链表结构
- 自动保存:每次数据变更后自动更新文件
四、使用说明
1. 编译运行
Windows系统:
gcc library.c -o library
library.exe
Linux/Mac系统:
gcc library.c -o library
./library
2. 操作流程示例
管理员操作:
- 选择"管理员登录"
- 添加图书:
- 搜索图书:输入"C程序"
-
读者操作:
- 选择"读者登录",输入任意ID(如:2023001)
- 借阅图书:输入ISBN号
- 查看图书:选择"查看所有图书"
- 归还图书:选择归还并输入ISBN号
3. 系统界面示例
======= 图书管理系统 ======= 1. 管理员登录 2. 读者登录 0. 退出系统 请选择: 1 ======= 管理员菜单 ======= 1. 添加图书 2. 搜索图书 3. 查看所有图书 0. 退出 请选择操作: 1 ======== 添加新书 ======== ISBN: 1234567890 书名: C程序设计语言 作者: 奇牛编程 总数量: 10 图书《C程序设计语言》添加成功!
五、扩展与优化建议
1. 可扩展功能
- 借阅记录持久化:添加
borrow.dat保存借阅记录 - 逾期计算:根据借阅时间自动计算逾期费用
- 管理员密码:增加管理员登录验证
- 批量导入:支持从CSV文件批量导入图书
2. 性能优化
// 示例:优化查找函数(哈希表实现) #define HASH_SIZE 100 typedef struct HashTable { Book *table[HASH_SIZE]; } HashTable; // ISBN哈希函数 unsigned int hash_function(char *isbn) { unsigned int hash = 0; for (int i = 0; i < strlen(isbn); i++) { hash = 31 * hash + isbn[i]; } return hash % HASH_SIZE; } // 添加图书到哈希表 void add_to_hash(Book *book, HashTable *hash_table) { unsigned int index = hash_function(book->isbn); book->next = hash_table->table[index]; hash_table->table[index] = book; }
3. 增强安全性
- 输入验证:添加更严格的ISBN格式检查
- 密码加密:管理员密码使用MD5/SHA加密存储
- 访问控制:不同读者只能查看自己的借阅记录
六、总结
这个C语言图书管理系统具有完整的功能实现、清晰的代码结构和良好的扩展性,适合用作课程设计或学习项目。系统特点包括:
- 采用链表数据结构动态管理数据
- 文件存储实现数据持久化
- 模块化设计便于功能扩展
- 完整的输入验证和错误处理
- 跨平台兼容性(Windows/Linux/Mac)
将整个代码复制到library.c文件中即可编译运行,无需任何外部依赖库。
资源推荐:
浙公网安备 33010602011771号