【数据结构】双向循环链表实现简易图书管理系统的增删改查

图书管理系统


使用双向循环链表实现一个简单的图书管理系统,图书管理系统有如下功能:
1.添加书籍
2.删除书籍
3.修改书籍信息
4.查询书籍信息
5.借书
6.还书

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 书籍结构体
struct book {char name[20];      // 书名char authorname[20]; // 作者名float price;        // 价格int num;            // 总数量int borrowed;       // 已借出数量
};// 双向循环链表节点
struct node {struct book data;struct node *prev;struct node *next;
};// 全局变量:链表头指针
struct node *head = NULL;// 函数声明
void add_book();
void delete_book();
void modify_book();
void search_book();
void borrow_book();
void return_book();
void display_all();
void free_list();
struct node* find_book(char *name);int main() {int choice;while (1) {printf("\n图书管理系统\n");printf("1. 添加书籍\n");printf("2. 删除书籍\n");printf("3. 修改书籍信息\n");printf("4. 查询书籍信息\n");printf("5. 借书\n");printf("6. 还书\n");printf("7. 显示所有书籍\n");printf("0. 退出\n");printf("请选择操作: ");scanf("%d", &choice);switch (choice) {case 1: add_book(); break;case 2: delete_book(); break;case 3: modify_book(); break;case 4: search_book(); break;case 5: borrow_book(); break;case 6: return_book(); break;case 7: display_all(); break;case 0: free_list(); return 0;default: printf("无效选择!\n");}}return 0;
}// 添加书籍
void add_book() {struct node *new_node = (struct node*)malloc(sizeof(struct node));if (!new_node) {printf("内存分配失败!\n");return;}printf("请输入书名: ");scanf("%s", new_node->data.name);printf("请输入作者名: ");scanf("%s", new_node->data.authorname);printf("请输入价格: ");scanf("%f", &new_node->data.price);printf("请输入总数量: ");scanf("%d", &new_node->data.num);new_node->data.borrowed = 0;if (!head) {head = new_node;head->next = head;head->prev = head;} else {new_node->next = head;new_node->prev = head->prev;head->prev->next = new_node;head->prev = new_node;}printf("书籍添加成功!\n");
}// 删除书籍
void delete_book() {if (!head) {printf("没有书籍可删除!\n");return;}char name[20];printf("请输入要删除的书名: ");scanf("%s", name);struct node *current = head;do {if (strcmp(current->data.name, name) == 0) {if (current->data.borrowed > 0) {printf("该书还有借出未还,不能删除!\n");return;}if (current == head) {if (head->next == head) {head = NULL;} else {head = head->next;}}current->prev->next = current->next;current->next->prev = current->prev;free(current);printf("书籍删除成功!\n");return;}current = current->next;} while (current != head);printf("未找到该书!\n");
}// 修改书籍信息
void modify_book() {if (!head) {printf("没有书籍可修改!\n");return;}char name[20];printf("请输入要修改的书名: ");scanf("%s", name);struct node *book = find_book(name);if (!book) {printf("未找到该书!\n");return;}printf("当前信息:\n");printf("书名: %s\n", book->data.name);printf("作者: %s\n", book->data.authorname);printf("价格: %.2f\n", book->data.price);printf("总数量: %d\n", book->data.num);printf("已借出: %d\n", book->data.borrowed);printf("\n请输入新的作者名: ");scanf("%s", book->data.authorname);printf("请输入新的价格: ");scanf("%f", &book->data.price);printf("请输入新的总数量: ");scanf("%d", &book->data.num);printf("书籍信息修改成功!\n");
}// 查询书籍信息
void search_book() {if (!head) {printf("没有书籍可查询!\n");return;}char name[20];printf("请输入要查询的书名: ");scanf("%s", name);struct node *book = find_book(name);if (!book) {printf("未找到该书!\n");return;}printf("\n书籍信息:\n");printf("书名: %s\n", book->data.name);printf("作者: %s\n", book->data.authorname);printf("价格: %.2f\n", book->data.price);printf("总数量: %d\n", book->data.num);printf("可借数量: %d\n", book->data.num - book->data.borrowed);
}// 借书
void borrow_book() {if (!head) {printf("没有书籍可借!\n");return;}char name[20];printf("请输入要借的书名: ");scanf("%s", name);struct node *book = find_book(name);if (!book) {printf("未找到该书!\n");return;}int available = book->data.num - book->data.borrowed;printf("当前可借数量: %d\n", available);if (available <= 0) {printf("该书已全部借出!\n");return;}int quantity;printf("请输入要借的数量: ");scanf("%d", &quantity);if (quantity <= 0) {printf("借书数量必须大于0!\n");return;}if (quantity > available) {printf("借书数量超过可借数量!\n");return;}book->data.borrowed += quantity;printf("借书成功! 当前已借出: %d\n", book->data.borrowed);
}// 还书
void return_book() {if (!head) {printf("没有书籍可还!\n");return;}char name[20];printf("请输入要还的书名: ");scanf("%s", name);struct node *book = find_book(name);if (!book) {printf("未找到该书!\n");return;}if (book->data.borrowed <= 0) {printf("该书没有借出记录!\n");return;}printf("当前已借出数量: %d\n", book->data.borrowed);int quantity;printf("请输入要还的数量: ");scanf("%d", &quantity);if (quantity <= 0) {printf("还书数量必须大于0!\n");return;}if (quantity > book->data.borrowed) {printf("还书数量超过已借出数量!\n");return;}book->data.borrowed -= quantity;printf("还书成功! 当前已借出: %d\n", book->data.borrowed);
}// 显示所有书籍
void display_all() {if (!head) {printf("没有书籍可显示!\n");return;}struct node *current = head;printf("\n所有书籍信息:\n");do {printf("\n书名: %s\n", current->data.name);printf("作者: %s\n", current->data.authorname);printf("价格: %.2f\n", current->data.price);printf("总数量: %d\n", current->data.num);printf("可借数量: %d\n", current->data.num - current->data.borrowed);current = current->next;} while (current != head);
}// 释放链表内存
void free_list() {if (!head) return;struct node *current = head;struct node *temp;do {temp = current;current = current->next;free(temp);} while (current != head);
}// 查找书籍
struct node* find_book(char *name) {if (!head) return NULL;struct node *current = head;do {if (strcmp(current->data.name, name) == 0) {return current;}current = current->next;} while (current != head);return NULL;
}

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

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

相关文章

强化学习入门--基本概念

强化学习基本概念 grid-world example 这个指的是一个小机器人&#xff08;agent&#xff09;在一个网格区域&#xff08;存在边界&#xff09;&#xff0c;网格中存在需要躲避的格子和目标格子&#xff0c;我们的目的就是找到到达目标格子的最短路径 state 表示智能体相对…

STMCubeMX配置STM32F103ZET6

1 配置时钟 配置RCC。 配置 SYS。将Timebase Source配置为TIM1, SysTick留给FreeRTOS用。 注意: 由于第一次配置的时候忘记配置这个步骤,导致工程第一次烧录成功后,后面一直无法烧录,报以下错误: keil no target connect Error: Flash Download failed - Target DLL h…

Leetcode:2239

1&#xff0c;题目 2&#xff0c;思路 循环遍历满足条件就记录&#xff0c;最后返回结果值 3&#xff0c;代码 public class Leetcode2239 {public static void main(String[] args) {System.out.println(new Solution2239().findClosestNumber(new int[]{-4, -2, 1, 4, 8})…

C语言之斗地主游戏

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 ​ C语言之斗地主游戏 目录 程序概述程序设计 Card类CardGroup类Player类LastCards类Land…

python编程-OpenCV(图像读写-图像处理-图像滤波-角点检测-边缘检测)图像变换

形态变换 图像处理中的形态学操作是处理图像结构的有效方法。以下是一些常见的形态学操作的介绍及其在 OpenCV 中的实现示例。 1. 腐蚀&#xff08;Erosion&#xff09; 腐蚀操作通过消除图像边界来减少图像中的白色区域&#xff08;前景&#xff09;&#xff0c;使物体的边…

【Prometheus】PromQL进阶用法

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

计算机网络介质访问控制全攻略:从信道划分到协议详解!!!

一、信道划分介质访问控制 介质访问控制&#xff1a;多个节点共享同一个“总线型”广播信道时&#xff0c;可能发生“信号冲突” 应该怎么控制各节点对传输介质的访问&#xff0c;才能减少冲突&#xff0c;甚至避免冲突? 时分复用(TDM) 时分复用&#xff1a;将时间分为等长的“…

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置

Prometheus部署及linux、mysql、monog、redis、RocketMQ、java_jvm监控配置 1.Prometheus部署1.2.Prometheus修改默认端口 2.grafana可视化页面部署3.alertmanager部署4.监控配置4.1.主机监控node-exporter4.2.监控mysql数据库mysqld_exporter4.3.监控mongod数据库mongodb_expo…

基于tldextract提取URL里的子域名、主域名、顶级域

TLD是TopLevel Domain的缩写。‌tldextract‌ 是一个用于从URL中提取子域、主域名和顶级域&#xff08;TLD&#xff09;的Python库。它利用公共后缀列表&#xff08;Public Suffix List&#xff09;来确保即使是复杂或不常见的URL结构也能被正确解析。tldextract能够处理包括IC…

常见Arthas命令与实践

Arthas 官网&#xff1a;https://arthas.aliyun.com/doc/&#xff0c;官方文档对 Arthas 的每个命令都做出了介绍和解释&#xff0c;并且还有在线教程&#xff0c;方便学习和熟悉命令。 Arthas Idea 的 IDEA 插件。 这是一款能快速生成 Arthas命令的插件&#xff0c;可快速生成…

win32汇编环境,对多行编辑框添加或删除文本

;运行效果 ;win32汇编环境,对多行编辑框添加或删除文本 ;主要要先设置文本的开始点与结束点&#xff0c;然后把一段文本顶替上去。没有添加文本或删除文本的概念&#xff0c;只有顶替。如果开始点与结束点都是前面文本的长度值&#xff0c;则成了从后面添加文本的效果。如果结束…

CSDN年度回顾:技术征途上的坚实步伐

嘿&#xff0c;时光过得可真快呀&#xff0c;就像那匹跑得飞快的白马&#xff0c;嗖的一下&#xff0c;2024 年的日历就这么悄无声息地翻到了最后一页。这会儿我回头看看在 CSDN 上度过的这一年&#xff0c;心里那叫一个感慨万千&#xff0c;满满的都是喜悦&#xff0c;就像心里…

人脸识别打卡系统--基于QT(附源码)

逃离舒适区 项目源代码放在我的仓库中&#xff0c;有需要自取 项目地址 https://gitcode.com/hujiahangdewa/Face_recognition.git 文章目录 一、项目结构分析二、服务器的搭建三、客户端的搭建四、人脸识别库的申请五、基于人脸识别库的识别判断六、QT人脸识别----调用百度ai…

人工智能在数字化转型中的角色:从数据分析到智能决策

引言 在数字化转型浪潮中&#xff0c;人工智能&#xff08;AI&#xff09;正迅速崛起&#xff0c;成为推动企业创新和变革的关键力量。面对日益复杂的市场环境和激烈的行业竞争&#xff0c;企业亟需借助技术手段提高运营效率、优化决策过程&#xff0c;并增强市场竞争力。而AI…

react install

react 安装 React 是一个用于构建用户界面的 JavaScript 库。以下是安装 React 的步骤&#xff1a; 使用 Create React App Create React App 是一个官方支持的命令行工具&#xff0c;用于快速搭建 React 应用。 安装 Node.js 和 npm 确保你的计算机上安装了 Node.js 和 npm…

Android系统开发(二十):字体活起来,安卓自定义字体改造指南

为什么要写这篇文章&#xff1f; 你是否厌倦了千篇一律的安卓默认字体&#xff1f;想让你的设备从“乏味的配角”变成“炫酷的主角”&#xff1f;好消息&#xff01;从Android 12到Android 15&#xff0c;自定义字体变得更简单、更强大。尤其是表情字体的更新&#xff0c;不仅…

将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch(3.纯python的实惠版)

前情&#xff1a; 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch&#xff08;1.标准版&#xff09;-CSDN博客 将 AzureBlob 的日志通过 Azure Event Hubs 发给 Elasticsearch&#xff08;2.换掉付费的Event Hubs&#xff09;-CSDN博客 python脚本实现 厉害的…

python学opencv|读取图像(四十)掩模:三通道图像的局部覆盖

【1】引言 前序学习了使用numpy创建单通道的灰色图像&#xff0c;并对灰色图像的局部进行了颜色更改&#xff0c;相关链接为&#xff1a; python学opencv|读取图像&#xff08;九&#xff09;用numpy创建黑白相间灰度图_numpy生成全黑图片-CSDN博客 之后又学习了使用numpy创…

Linux系统常用指令

查找文件 find / -name "<文件名>" 2>/dev/null //遍历系统查找指定文件名文件ls -l | grep "<文件名>" //列出当前目录下有关文件名的文件find -name sw_sfp_alarm_cfg.xml //查找文件名对应路径 切换目录 编辑文件 vi <文件…

【Unity】ScrollViewContent适配问题(Contentsizefilter不刷新、ContentSizeFilter失效问题)

最近做了一个项目&#xff0c;菜单栏读取数据后自动生成&#xff0c;结果用到了双重布局 父物体 尝试了很多方式&#xff0c;也看过很多大佬的文章&#xff0c;后来自己琢磨了一下&#xff0c;当子物体组件自动生成之后&#xff0c;使用以下以下代码效果会好一些&#xff1a; …