当前位置: 首页 > news >正文

C语言编写简易图书管理系统

这篇文章介绍了一个基本的图书管理系统的实现,它允许用户添加、插入、删除、修改、显示和查询图书的功能。该系统通过使用二进制文件将图书信息保存到磁盘,并且在程序启动时能够加载已保存的图书信息。

介绍

在计算机科学中,图书管理系统是一种用于管理和维护图书馆或个人藏书的系统。它可以帮助用户记录、跟踪和查找图书信息。图书管理系统通常包括一系列功能,如添加、删除、修改、查询和显示图书等,以提高图书的管理效率。

功能项解释
  1. 添加书籍:用户可以输入书籍的标题、作者和出版年份,然后将图书信息添加到系统中。添加的图书信息将被保存到磁盘文件中。
  2. 插入书籍:用户可以选择一个位置,将书籍插入到指定位置。插入书籍时,系统会将后面的书籍向后移动一个位置。插入书籍后,系统会将修改后的图书信息保存到磁盘文件中。
  3. 删除书籍:用户可以选择要删除的书籍位置,然后系统将删除该位置上的书籍,并将后面的书籍向前移动一个位置。删除后的图书信息将被保存到磁盘文件中。
  4. 修改书籍:用户可以选择要修改的书籍位置,然后输入新的标题、作者和出版年份进行修改。修改后的图书信息将被保存到磁盘文件中。
  5. 显示书籍:系统将显示已添加的所有图书信息。如果没有添加任何图书,系统将显示相应提示信息。
  6. 查询书籍:用户可以根据输入内容逐一匹配图书标题、作者和年份,在符合条件的图书中查询。查询结果将显示所有符合条件的图书信息。
相关知识点解释

在这个图书管理系统中,使用了结构体(struct)来存储每本书的信息。结构体是一种自定义的数据类型,它可以包含不同类型的数据,例如字符串和整数。在这个系统中,Book 结构体包含了书籍的标题(title)、作者(author)和出版年份(year)。

文件操作也是这个系统的关键特性之一。文件是计算机存储数据的一种方式,它可以将数据长久地保存在磁盘上。在这个系统中,通过使用文件操作函数(如 fopen、fwrite 和 fread)将图书信息保存到名为 “library.dat” 的二进制文件中,以及从该文件读取已保存的图书信息并加载到程序中。具体来说,使用二进制模式(“wb” 或 “rb”)打开文件来进行写入和读取操作。

另外,这个系统中使用了循环和条件语句来实现不同的功能。通过使用循环(如 do-while 循环),使程序能够反复执行一系列操作,直到用户选择退出。通过使用条件语句(如 switch-case 语句),根据用户选择的功能选项执行相应的操作。

代码解析
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

由于程序中使用了标准输入输出库(stdio.h)、标准库(stdlib.h)和字符串库(string.h),因此需要包含这些库的头文件。

typedef struct {char title[100];char author[100];int year;
} Book;

定义了一个名为 Book 的结构体类型,包含了三个成员变量:title(标题)、author(作者)和 year(年份)。这个结构体类型用于存储图书的信息。

void addBook(Book *books, int *count) {// ...
}

定义了一个名为 addBook 的函数,用于添加书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void insertBook(Book *books, int *count) {// ...
}

定义了一个名为 insertBook 的函数,用于插入书籍。这个函数同样接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void deleteBook(Book *books, int *count) {// ...
}

定义了一个名为 deleteBook 的函数,用于删除书籍。这个函数同样接受两个参数:指向 Book 结构体数组的指针(books)和指向整数变量的指针(count)。

void modifyBook(Book *books, int count) {// ...
}

定义了一个名为 modifyBook 的函数,用于修改书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

void displayBooks(Book *books, int count) {// ...
}

定义了一个名为 displayBooks 的函数,用于显示书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

void searchBooks(Book *books, int count) {// ...
}

定义了一个名为 searchBooks 的函数,用于查询书籍。这个函数接受两个参数:指向 Book 结构体数组的指针(books)和整数变量(count)。

int main() {// ...
}

定义了一个 main 函数,它是程序的主函数,程序从这里开始执行。

完整代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>typedef struct {char title[100];char author[100];int year;
} Book;void addBook(Book *books, int *count) {char title[100];char author[100];int year;printf("请输入书籍标题:");scanf("%s", title);printf("请输入书籍作者:");scanf("%s", author);printf("请输入书籍出版年份:");scanf("%d", &year);Book book;strcpy(book.title, title);strcpy(book.author, author);book.year = year;books[*count] = book;(*count)++;FILE *file = fopen("library.dat", "ab");if (file == NULL) {printf("无法打开文件\n");exit(1);}fwrite(&book, sizeof(Book), 1, file);fclose(file);printf("添加书籍成功!\n");
}void insertBook(Book *books, int *count) {char title[100];char author[100];int year;int position;printf("请输入要插入的位置:");scanf("%d", &position);if (position < 0 || position > (*count)) {printf("无效的位置\n");return;}printf("请输入书籍标题:");scanf("%s", title);printf("请输入书籍作者:");scanf("%s", author);printf("请输入书籍出版年份:");scanf("%d", &year);Book book;strcpy(book.title, title);strcpy(book.author, author);book.year = year;for (int i = *count; i > position; i--) {books[i] = books[i - 1];}books[position] = book;(*count)++;FILE *file = fopen("library.dat", "wb");if (file == NULL) {printf("无法打开文件\n");exit(1);}for (int i = 0; i < *count; i++) {fwrite(&books[i], sizeof(Book), 1, file);}fclose(file);printf("插入书籍成功!\n");
}void deleteBook(Book *books, int *count) {int position;printf("请输入要删除的位置:");scanf("%d", &position);if (position < 0 || position >= (*count)) {printf("无效的位置\n");return;}for (int i = position; i < (*count) - 1; i++) {books[i] = books[i + 1];}(*count)--;FILE *file = fopen("library.dat", "wb");if (file == NULL) {printf("无法打开文件\n");exit(1);}for (int i = 0; i < *count; i++) {fwrite(&books[i], sizeof(Book), 1, file);}fclose(file);printf("删除书籍成功!\n");    
}void modifyBook(Book *books, int count) {int position;printf("请输入要修改的位置:");scanf("%d", &position);if (position < 0 || position >= count) {printf("无效的位置\n");return;}printf("请输入要修改的书籍标题:");scanf("%s", books[position].title);printf("请输入要修改的书籍作者:");scanf("%s", books[position].author);printf("请输入要修改的书籍出版年份:");scanf("%d", &books[position].year);FILE *file = fopen("library.dat", "wb");if (file == NULL) {printf("无法打开文件\n");exit(1);}for (int i = 0; i < count; i++) {fwrite(&books[i], sizeof(Book), 1, file);}fclose(file);printf("修改书籍成功!\n");
}void displayBooks(Book *books, int count) {if (count == 0) {printf("暂无书籍信息\n");} else {printf("图书列表:\n");for (int i = 0; i < count; i++) {printf("书籍标题: %s\n", books[i].title);printf("书籍作者: %s\n", books[i].author);printf("书籍出版年份: %d\n", books[i].year);printf("--------------------\n");}}
}void searchBooks(Book *books, int count) {char query[100];printf("请输入要查询的内容:");scanf("%s", query);printf("查询结果:\n");for (int i = 0; i < count; i++) {if (strstr(books[i].title, query) != NULL || strstr(books[i].author, query) != NULL || books[i].year == atoi(query)) {printf("书籍标题: %s\n", books[i].title);printf("书籍作者: %s\n", books[i].author);printf("书籍出版年份: %d\n", books[i].year);printf("--------------------\n");}}
}int main() {Book books[100];int count = 0;FILE *file = fopen("library.dat", "rb");if (file != NULL) {while (!feof(file)) {Book book;fread(&book, sizeof(Book), 1, file);if (!feof(file)) {books[count] = book;count++;}}fclose(file);}int choice;do {printf("欢迎使用图书管理系统\n");printf("1. 添加书籍\n");printf("2. 插入书籍\n");printf("3. 删除书籍\n");printf("4. 修改书籍\n");printf("5. 显示书籍\n");printf("6. 查询书籍\n");printf("0. 退出\n");printf("请输入选项: ");scanf("%d", &choice);switch (choice) {case 1:addBook(books, &count);break;case 2:insertBook(books, &count);break;case 3:deleteBook(books, &count);break;case 4:modifyBook(books, count);break;case 5:displayBooks(books, count);break;case 6:searchBooks(books, count);break;case 0:printf("谢谢使用,再见!\n");break;default:printf("无效的选项,请重新输入\n");}printf("\n");} while (choice != 0);return 0;
}

运行测试如下:测试运行

相关文章:

C语言编写简易图书管理系统

这篇文章介绍了一个基本的图书管理系统的实现&#xff0c;它允许用户添加、插入、删除、修改、显示和查询图书的功能。该系统通过使用二进制文件将图书信息保存到磁盘&#xff0c;并且在程序启动时能够加载已保存的图书信息。 介绍 在计算机科学中&#xff0c;图书管理系统是…...

C++入门 第一篇(C++关键字, 命名空间,C++输入输出)

目录 1. C关键字 2. 命名空间 2.1 命名空间定义 2.2命名空间的使用 命名空间的使用有三种方式&#xff1a; 1.加命名空间名称及作用域限定符 2.使用using将命名空间中某个成员引入 3.使用using namespace 命名空间名称 引入 3. C输入&输出 4.缺省函数 4.1 缺省参…...

python股票波动性分析

一、简介 我们都经历过这样的情况——盯着股票图表,试图理解那些疯狂的价格上涨,或者只是想知道为什么突然平静。在这些波动中,有一个一致的因素常常脱颖而出:波动性。了解波动性为衡量任何特定点的市场情绪和情绪提供了一个视角。通过剖析波动性的细微差别,我们不仅可以更…...

53 打家劫舍

打家劫舍 题解1 DP1题解2 DP2 &#xff01;经典DP&#xff01; 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果 两间相邻的房屋在同一晚上被小偷闯入…...

CentOS 7 基于C 连接ZooKeeper 客户端

前提条件&#xff1a;CentOS 7 编译ZooKeeper 客户端&#xff0c;请参考&#xff1a;CentOS 7 编译ZooKeeper 客户端 1、Docker 安装ZooKeeper # docker 获取zookeeper 最新版本 docker pull zookeeper# docker 容器包含镜像查看 docker iamges# 准备zookeeper 镜像文件挂载对…...

2023-2024-1 for循环-1(15-38)

7-15 输出闰年 输出21世纪中截止某个年份以来的所有闰年年份。注意&#xff1a;闰年的判别条件是该年年份能被4整除但不能被100整除、或者能被400整除。 输入格式: 输入在一行中给出21世纪的某个截止年份。 输出格式: 逐行输出满足条件的所有闰年年份&#xff0c;即每个年…...

初级问题 程序中的变量是指什么?中级问题 把若干个数据沿直线排列起来的数据结构叫作什么?高级问题 栈和队列的区别是什么?

目录 1.深刻主题 2.描写复杂人物 初级问题 程序中的变量是指什么&#xff1f; 中级问题 把若干个数据沿直线排列起来的数据结构叫作什么&#xff1f; 高级问题 栈和队列的区别是什么&#xff1f; 计算机图形学&#xff08;有效边表算法&#xff09; 介绍一下计算机图形学…...

clickhouse数据库简介,列式存储

clickhouse数据库简介 1、关于列存储 所说的行式存储和列式存储&#xff0c;指的是底层的存储形式&#xff0c;数据在磁盘上的真实存储&#xff0c;至于暴漏在上层的用户的使用是没有区别的&#xff0c;看到的都是一行一行的表格。 idnameuser_id1闪光10266032轨道物流10265…...

flask 发送ajax

前端 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <script src"https://cdn.lyshark.com/javascript/jquery/3.5.1/jquery.min.js"…...

Android Gradle 命令打包AAR

平台 Android Archive (AAR) 文件是一种特定于Android的存档文件格式&#xff0c;用于将Android库和资源打包成单个可重用的单元。AAR文件通常用于共享和分发Android库&#xff0c;以便其他Android应用项目可以轻松引用和使用这些库。 AAR文件是一种便捷的方式&#xff0c;用于…...

如何导出带有材质的GLB模型?

1、为什么要使用 GLB 模型? GLB格式&#xff08;GLTF Binary&#xff09;是一种用于存储和传输3D模型及相关数据的文件格式&#xff0c;具有以下优点和作用&#xff1a; 统一性&#xff1a;GLB是一种开放标准的3D文件格式&#xff0c;由Khronos Group制定和维护。它融合了GL…...

C/C++面试常见知识点

目录 C/C语言C内存分区malloc/free与new/delete的区别联合体联合体大小的计算 结构体对齐为什么需要结构体内存对齐 结构体与联合体的区别左值引用与右值引用指针和引用的区别迭代器失效static关键字在C语言的作用进程地址空间的分布内联函数 三大特性构造函数不能是虚函数析构…...

详细介绍数据结构-堆

计算机中的堆数据结构 什么是堆 在计算机科学中&#xff0c;堆&#xff08;Heap&#xff09;是一种重要的数据结构&#xff0c;它用于在动态分配时存储和组织数据。堆是一块连续的内存区域&#xff0c;其中每个存储单元&#xff08;通常是字节&#xff09;都与另一个存储单元…...

001flutter基础学习

flutter基础学习 参考:https://book.flutterchina.club/chapter1/flutter_intro.html Flutter是谷歌的移动UI框架跨平台: Linux,Android, IOS,Fuchsia原生用户界面:它是原生的,让我们体验更好,性能更好开源免费&#xff1a;完全开源,可以进行商用Flutter与主流框架的对比 Cor…...

leetCode 1143.最长公共子序列 动态规划 + 图解

此题我的往期文章推荐&#xff1a; leetCode 1143.最长公共子序列 动态规划 滚动数组-CSDN博客https://blog.csdn.net/weixin_41987016/article/details/133689692?spm1001.2014.3001.5501leetCode 1143.最长公共子序列 一步步思考动态规划 优化空间复杂度_呵呵哒(&#xf…...

解密人工智能:KNN | K-均值 | 降维算法 | 梯度Boosting算法 | AdaBoosting算法

文章目录 一、机器学习算法简介1.1 机器学习算法包含的两个步骤1.2 机器学习算法的分类 二、KNN三、K-均值四、降维算法五、梯度Boosting算法和AdaBoosting算法六、结语 一、机器学习算法简介 机器学习算法是一种基于数据和经验的算法&#xff0c;通过对大量数据的学习和分析&…...

Python深度学习实践

线性模型 课程 import numpy as np import matplotlib.pyplot as plt x_data[1.0,2.0,3.0] y_data[2.0,4.0,6.0] #前馈函数 def forward(x):return x*w #损失函数 def loss(x,y):y_predforward(x)return (y_pred-y)*(y_pred-y) w_list[] mse_list[] for w in np.arange(0.0,4…...

VS2017+QT+PCL环境配置

前言: 最近自己再弄一下小项目中需要用到pcl来开发点云的显示,但是却遇到很多坑,所以记录下来分析给知音人。 避雷:由于vtk和pcl之间有版本以来关系,但是安装过程是不变的。 选择对应的版本参考如下安装: pcl1.8.1依赖vtk版本7.1.1;pcl1.9.1至pcl1.12.0依赖vtk最低版本为…...

207、SpringBoot 整合 RabbitMQ 实现消息的发送 与 接收(监听器)

目录 ★ 发送消息★ 创建队列的两种方式代码演示需求1&#xff1a;发送消息1、ContentUtil 先定义常量2、RabbitMQConfig 创建队列的两种方式之一&#xff1a;配置式&#xff1a;问题&#xff1a; 3、MessageService 编写逻辑PublishController 控制器application.properties 配…...

想要精通算法和SQL的成长之路 - 滑动窗口和大小根堆

想要精通算法和SQL的成长之路 - 滑动窗口和大小根堆 前言一. 大小根堆二. 数据流的中位数1.1 初始化1.2 插入操作1.3 完整代码 三. 滑动窗口中位数3.1 在第一题的基础上改造3.2 栈的remove操作 前言 想要精通算法和SQL的成长之路 - 系列导航 一. 大小根堆 先来说下大小根堆是什…...

linux之kylin系统nginx的安装

一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源&#xff08;HTML/CSS/图片等&#xff09;&#xff0c;响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址&#xff0c;提高安全性 3.负载均衡服务器 支持多种策略分发流量…...

应用升级/灾备测试时使用guarantee 闪回点迅速回退

1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间&#xff0c; 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点&#xff0c;不需要开启数据库闪回。…...

3.3.1_1 检错编码(奇偶校验码)

从这节课开始&#xff0c;我们会探讨数据链路层的差错控制功能&#xff0c;差错控制功能的主要目标是要发现并且解决一个帧内部的位错误&#xff0c;我们需要使用特殊的编码技术去发现帧内部的位错误&#xff0c;当我们发现位错误之后&#xff0c;通常来说有两种解决方案。第一…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

Rapidio门铃消息FIFO溢出机制

关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系&#xff0c;以下是深入解析&#xff1a; 门铃FIFO溢出的本质 在RapidIO系统中&#xff0c;门铃消息FIFO是硬件控制器内部的缓冲区&#xff0c;用于临时存储接收到的门铃消息&#xff08;Doorbell Message&#xff09;。…...

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决

Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中&#xff0c;新增了一个本地验证码接口 /code&#xff0c;使用函数式路由&#xff08;RouterFunction&#xff09;和 Hutool 的 Circle…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...

掌握 HTTP 请求:理解 cURL GET 语法

cURL 是一个强大的命令行工具&#xff0c;用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中&#xff0c;cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...