当前位置: 首页 > 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的成长之路 - 系列导航 一. 大小根堆 先来说下大小根堆是什…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...