【C语言】图书管理系统(文件存储版)丨源码+详解

一、系统介绍

这是一个基于C语言开发的终端图书管理系统,采用链表数据结构​+​二进制文件存储技术实现。系统具有以下特点:

  1. 双角色系统​:管理员(管理图书)和读者(借阅/归还)
  2. 完整功能​:图书添加、搜索、借阅、归还、显示等功能
  3. 数据持久化​:所有图书信息保存在文件中,重启不丢失
  4. 健壮性设计​:完善的输入验证和错误处理

二、系统完整代码

#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];        // 借阅者IDchar book_isbn[MAX_ID];      // 图书ISBNtime_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(&current->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保存所有图书数据,采用以下技术:

  1. 序列化存储​:直接将内存中的结构体写入文件
  2. 链表遍历​:通过fwrite逐个节点写入文件
  3. 读取加载​:启动时重新构建链表结构
  4. 自动保存​:每次数据变更后自动更新文件

四、使用说明

1. 编译运行

Windows系统:​

gcc library.c -o library
library.exe

Linux/Mac系统:​

gcc library.c -o library
./library

2. 操作流程示例

管理员操作:​

  1. 选择"管理员登录"
  2. 添加图书:
  3. 搜索图书:输入"C程序"

读者操作:​

  1. 选择"读者登录",输入任意ID(如:2023001)
  2. 借阅图书:输入ISBN号
  3. 查看图书:选择"查看所有图书"
  4. 归还图书:选择归还并输入ISBN号

3. 系统界面示例

======= 图书管理系统 =======
1. 管理员登录
2. 读者登录
0. 退出系统
请选择: 1======= 管理员菜单 =======
1. 添加图书
2. 搜索图书
3. 查看所有图书
0. 退出
请选择操作: 1======== 添加新书 ========
ISBN: 1234567890
书名: C程序设计语言
作者: XXXX
总数量: 10图书《C程序设计语言》添加成功!

五、扩展与优化建议

1. 可扩展功能

  1. 借阅记录持久化​:添加borrow.dat保存借阅记录
  2. 逾期计算​:根据借阅时间自动计算逾期费用
  3. 管理员密码​:增加管理员登录验证
  4. 批量导入​:支持从CSV文件批量导入图书

2. 性能优化

// 示例:优化查找函数(哈希表实现)
#define HASH_SIZE 100typedef 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. 增强安全性

  1. 输入验证​:添加更严格的ISBN格式检查
  2. 密码加密​:管理员密码使用MD5/SHA加密存储
  3. 访问控制​:不同读者只能查看自己的借阅记录

六、总结

这个C语言图书管理系统具有完整的功能实现、清晰的代码结构和良好的扩展性,适合用作课程设计或学习项目。系统特点包括:

  1. 采用链表数据结构动态管理数据
  2. 文件存储实现数据持久化
  3. 模块化设计便于功能扩展
  4. 完整的输入验证和错误处理
  5. 跨平台兼容性(Windows/Linux/Mac)

将整个代码复制到library.c文件中即可编译运行,无需任何外部依赖库。

 资源推荐:

C/C++学习交流君羊

C/C++教程

C/C++学习路线,就业咨询,技术提升

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/83794.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java求职者面试题解析:Spring、Spring Boot、MyBatis框架与源码原理

Java求职者面试题解析&#xff1a;Spring、Spring Boot、MyBatis框架与源码原理 第一轮&#xff1a;基础概念问题 1. 请解释什么是Spring框架&#xff1f;它的核心特性有哪些&#xff1f; Spring是一个开源的Java/Java EE应用程序框架&#xff0c;用于简化企业级应用开发。其…

【Chipyard】修改Gemmini 中PE的数量

实战目标 PE数量扩大到原来4倍 原来配置 tileRows: Int 1,tileColumns: Int 1,meshRows: Int 16,meshColumns: Int 16, 改后配置 tileRows: Int 1,tileColumns: Int 1,meshRows: Int 32,meshColumns: Int 32, 修改配置 1. 修改gemmini的scala配置文件&#xff0c;用…

TCP客户端进程分割输入输出

创建TCP客户端&#xff0c;创建子进程分割TCP客户端的read功能和write功能&#xff0c;实现分割I/O的目的。加快客户端速率。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <signal.h> #include …

Wi-Fi 6 在 2.4GHz 频段的速率与优化分析

Wi-Fi 6&#xff08;802.11ax&#xff09;在 2.4GHz 和 5GHz 频段均可工作&#xff0c;理论最高速率可达 1200 Mbps&#xff08;5GHz&#xff0c;80MHz&#xff0c;22 MIMO&#xff09;。但在 2.4GHz 频段&#xff0c;速率受 信道宽度、MIMO、调制方式、干扰、协议开销 影响&am…

WPF--Application.Current.Dispatcher.BeginInvoke

1.代码示例 private void LogInfoList_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) {// 直接在这里修改集合会引发递归if (e.Action NotifyCollectionChangedAction.Add){if (logInfoList.Count > 200){logInfoList.RemoveAt(0); // 这里会…

ZooKeeper详解以及应用部署(AI)

ZooKeeper 是一个开源的分布式协调服务框架&#xff0c;旨在为分布式应用提供一致性保障和关键协调功能。其核心设计理念是将复杂的分布式一致性逻辑封装为简单可靠的接口&#xff0c;让开发者专注于业务逻辑而非底层协调难题。以下是其核心要点&#xff1a; &#x1f9e0; 一、…

将MySQL数据库中所有表和字段编码统一改为utf8mb4_unicode_ci

完整操作步骤 1. 首先修改数据库默认字符集 sql ALTER DATABASE 你的数据库名 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 2. 生成批量修改所有表的SQL语句 sql SELECT CONCAT(ALTER TABLE , table_schema, ., table_name, CONVERT TO CHARACTER SET utf8mb4 C…

jupyterhub的浅浅使用-重点在解决无法登录

jupyterhub的浅浅使用-重点在解决无法登录 jupyterhub的浅浅使用-重点在解决无法登录1、jupyterhub是什么2、创建Dockerfile3、启动容器3.1、生成配置文件jupyterhub --generate-config3.2、运行容器3.3、进入容器配置用户密码3.4、访问127.0.0.1:8000并登录 4、后台创建的用户…

【Bitcoin基础】比特币的地址格式有哪些?如何应用?

比特币地址格式的分类及应用场景 比特币地址是用于接收和发送比特币的标识符&#xff0c;主要有以下几种格式&#xff0c;每中类型都有其特定的用途和特点: 比特币地址格式 P2PKH 1xxxx leagcy地址 P2SH 3xxxx 允许更复杂的交易多重签名 bech32 bc1xxxx bech32mP2TR…

3.1.2_栈的顺序存储实现

知识总览&#xff1a; 顺序栈的定义&#xff1a; 顺序栈是用顺序存储实现的 &#xff0c;代码定义方式和顺序表类似(啥是顺序表来着&#xff1f;&#xff1f;&#xff1f;) 定义一个顺序栈struct结构体SqStack&#xff0c;结构体中有静态数组data来存放栈里边的元素1个int型的…

JavaEE初阶第一期:计算机是如何 “思考” 的(上)

专栏&#xff1a;JavaEE初阶起飞计划 个人主页&#xff1a;手握风云 一、冯诺依曼体系结构 1.1. 概念 冯诺依曼体系结构&#xff08;Von Neumann Architecture&#xff09;&#xff0c;是现代计算机的基础设计概念&#xff0c;核心思想是“存储程序控制”。具体来说&#xff0c…

SQL Server全局搜索:在整个数据库中查找特定值的高效方法

SQL Server全局搜索&#xff1a;在整个数据库中查找特定值的高效方法 一、需求背景&#xff1a;为什么需要数据库全局搜索&#xff1f; 在数据库管理和开发过程中&#xff0c;我们经常会遇到这样的场景&#xff1a; 只记得某个数据值&#xff0c;但忘记了它所在的表或列需要…

万物皆数:构建数字信号处理的数学基石

万物皆数&#xff1a;构建数字信号处理的数学基石 欢迎来到数字信号处理&#xff08;DSP&#xff09;的世界。在这里&#xff0c;声音、图像、通信信号、医疗数据……一切信息都被转化为一串串冰冷的数字。然而&#xff0c;正是通过对这些数字的精妙运算&#xff0c;我们得以实…

到院率最高提升40%,消费医疗用AI营销机器人跑赢增长焦虑

当前&#xff0c;消费医疗机构普遍依赖人工咨询师进行客户接待和营销咨询。然而&#xff0c;专业咨询师缺口高达20万人&#xff0c;大量“护士转咨询”“销售转咨询”现象导致方案设计专业性不足&#xff0c;客户投诉率提升40%。人工客服不仅医学知识薄弱&#xff0c;学习能力有…

【推荐算法】注意力机制与兴趣演化:推荐系统如何抓住用户的心?

注意力机制与兴趣演化&#xff1a;推荐系统如何抓住用户的心&#xff1f; 一、算法背景知识&#xff1a;从静态推荐到动态感知1.1 传统推荐系统的局限性1.2 人类注意力机制的启示 二、算法理论/结构&#xff1a;动态兴趣建模革命2.1 DIN&#xff08;深度兴趣网络&#xff09;&a…

快速入门:创建 Azure 数据资源管理器群集和数据库

前言 Azure 数据资源管理器是 Microsoft 提供的一项快速、完全托管的数据分析服务。 它允许用户分析来自应用程序、网站、物联网设备等的海量数据流,从而简化复杂的数据探索。 它能够处理数 PB 的数据,并支持快速检索数据以进行分析。 主要特点 高性能:ADX 针对快速数据提…

Redis集群模式之Redis Cluster(2)

上篇文章我们讲解了Redis Cluster中的主要模块和两种重定向方式&#xff0c;这篇文章我们来讲解一下Redis Cluster的状态监测和维护。 Redis Cluster状态监测及维护 要讲解Redis Cluster中节点的状态如何维护&#xff0c;我们要先知道Redis Cluster中的节点有哪些状态&#xf…

Step-Audio-AQAA 解读:迈向「纯语音」交互的端到端 LALM 新里程

引言:AI 从听到说 大型音频语言模型(Large Audio-Language Models, LALMs)正在彻底改变我们与机器交互的方式。我们不再满足于简单的文本问答,而是期望 AI 能够像人类一样,通过自然的语音进行交流,理解我们的意图,并以富有表现力的声音回应。然而,构建一个能够直接从语…

基于边缘计算的丝杆状态实时监测系统设计?

基于边缘计算的丝杆状态实时监测系统设计&#xff0c;可从系统架构、各层功能设计、关键技术应用等方面入手&#xff0c;以下为详细介绍&#xff1a; 系统架构设计 基于边缘计算的丝杆状态实时监测系统通常由感知层、边缘层和云端三部分组成。感知层负责数据采集&#xff0c;…

LeetCode 每日一题 2025/6/9-2025/6/15

记录了初步解题思路 以及本地实现代码&#xff1b;并不一定为最优 也希望大家能一起探讨 一起进步 目录 6/9 440. 字典序的第K小数字6/10 3442. 奇偶频次间的最大差值 I6/11 3445. 奇偶频次间的最大差值 II6/12 3423. 循环数组中相邻元素的最大差值6/13 2616. 最小化数对的最大…