【零基础学数据结构】顺序表实现书籍存储

目录

书籍存储的实现规划

​编辑 前置准备:

 书籍结构体:

书籍展示的初始化和文件加载

书籍展示的销毁和文件保存

 书籍展示的容量检查

 书籍展示的尾插实现

 书籍展示的书籍增加

 书籍展示的书籍打印

 书籍删除展示数据

书籍展示修改数据

在指定位置之前删除数据

 书籍查找展示数据

 测试文件:

 源代码文件:


书籍存储的实现规划

 前置准备:

文件前置创建:

  1. BookList.h  -  头文件声明
  2. BookList.c  -  实现功能
  3. text.c           -  测试文件
  • 创建书籍结构体
  • 创建动态内存

  BookList 结构体的创建
 为了方便后续更改,我们有以下定义
 1.书名  2.作者  3.价格  4.分类  5.编号

#define BOOKNAME 100
#define AUTHOR 50
#define TYPE 30
#define ID 50

 书籍结构体:

typedef struct BookList
{
	char book_name[BOOKNAME]; //书名
	char author[AUTHOR];      //作者
	float price;			  //价格
	char type[TYPE];		  //分类
	char id[ID];			  //编号
}BookList;

 定义类型方便更改

typedef BookList SLDataType;

创建动态顺序表 

typedef struct Book
{
	SLDataType* arr;        //指针变量,指向结构体类型元素的数组
	int size;				//有效数据的个数
	int capacity;			//空间容量大小
}Book;

书籍展示的初始化和文件加载

void BookInit(Book* book);
void LoadBook(Book* book);
// 书籍展示的初始化和文件加载
void BookInit(Book* book)
{
	book->arr = NULL;
	book->size = book->capacity = 0;
	LoadBook(book);
}

void LoadBook(Book* book)
{
	FILE* pf = fopen("booklist", "rb");
	if (NULL == pf)
	{
		perror("fopen booklist error!");
		return;
	}

	//加载文件
	BookList b2;
	while (fread(&b2, sizeof(BookList), 1, pf))
	{
		//尾插
		BookPushBack(book, b2);
	}
	printf("数据加载成功!\n");
	fclose(pf);
	pf = NULL;
}

书籍展示的销毁和文件保存

void BookDestroy(Book* book);
void SaveBook(Book* book);
// 书籍展示的销毁和文件保存
void SLDestroy(Book* ps)
{
	if (ps->arr==NULL)   //判断ps->arr是否为NULL,如果不为NULL,说明空间需要释放
	{
		free(ps->arr);
	}
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

void BookDestroy(Book* book)
{
	SaveBook(book);
	SLDestroy(book);
}

// 图书书籍存储
void SaveBook(Book* book)
{
	FILE* pd = fopen("booklist", "wb");
	if (NULL == pd)
	{
		perror("fopen booklist error!");
		return;
	}

	// 存储书籍数据
	for (int i = 0; i < book->size; i++)
	{
		fwrite(book->arr+i, sizeof(BookList), 1, pd);
	}
	printf("数据保存成功!\n");
	fclose(pd);
	pd = NULL;
}

 书籍展示的容量检查

void BookCheckCapacity(Book* book);
// 书籍展示的容量检查
void BookCheckCapacity(Book* book)
{
	if (book->capacity == book->size)
	{
		int newcapacity = book->capacity == 0 ? 4 : book->capacity * 2;
		//动态内存分配
		SLDataType* tmp = (SLDataType*)realloc(book->arr, newcapacity * sizeof(SLDataType));
		if (NULL == tmp)
		{
			perror("realloc error!");
			return;
		}
		book->arr = tmp;
		book->capacity = newcapacity;
	}
}

 书籍展示的尾插实现

void BookPushBack(Book* book, SLDataType x);
// 书籍展示的尾插实现
void BookPushBack(Book* book, SLDataType x)
{
	assert(book);
	//尾插之前检查内存是否够
	BookCheckCapacity(book);

	//进行尾插
	book->arr[book->size++] = x;
}

 书籍展示的书籍增加

void BookAdd(Book* book);
// 书籍展示的书籍增加
void BookAdd(Book* book)
{

	// 1.书名  2.作者  3.价格  4.分类  5.编号
	BookList b1;
	printf("请输入你要添加的书籍名字:\n");
	scanf("%s", b1.book_name);

	printf("请输入你要添加的书籍作者:\n");
	scanf("%s", b1.author);

	printf("请输入你要添加的书籍价格:\n");
	scanf("%f", &(b1.price));

	printf("请输入你要添加的书籍分类:\n");
	scanf("%s", b1.type);

	printf("请输入你要添加的书籍编号:\n");
	scanf("%s", b1.id);

	// 添加数据
	BookPushBack(book, b1);
	printf("添加成功!\n");
}

 书籍展示的书籍打印

void BookPint(Book* book);
// 书籍展示的书籍打印
void BookPint(Book* book)
{
	// 1.书名  2.作者  3.价格  4.分类  5.编号
	printf("%-10s %-10s %-10s %-10s %-15s\n", "书名", "作者", "价格", "分类", "编号");
	printf("-------------------------------------------------------------\n");
	for (int i = 0; i < book->size; i++)
	{
		printf("%-10s %-10s %-10.1f %-10s %-15s\n",
			book->arr[i].book_name,
			book->arr[i].author,
			book->arr[i].price,
			book->arr[i].type,
			book->arr[i].id
		);
	}
}

 书籍删除展示数据

void BookDel(Book* book);
//删除书籍展示数据
void BookDel(Book* book)
{
	// 在删除之前先检查数据存不存在
	char name[BOOKNAME];
	printf("请输入您需要删除的书籍:\n");
	scanf("%s", name);

	int find = FindByName(book, name);
	if (find < 0)
	{
		printf("无法找到需要删除的图书\n");
		return;
	}
	SLErase(book, find);
	printf("删除成功!\n");
}

书籍展示修改数据

void BookModify(Book* book);
//书籍展示修改数据
void BookModify(Book* book)
{
	//要修改的书籍需要存在
	char name[BOOKNAME];
	printf("请输入你需要修改的图书名字:\n");
	scanf("%s", name);

	//查找书籍看是否存在
	int find = FindByName(book, name);
	if (find < 0)
	{
		printf("无法找到需要修改的图书\n");
		return;
	}

	//直接修改
	printf("请输入新的图书名字:\n");
	scanf("%s", book->arr[find].book_name);

	printf("请输入新的图书作者:\n");
	scanf("%s", book->arr[find].author);

	printf("请输入新的图书价格:\n");
	scanf("%f", &(book->arr[find].price));

	printf("请输入新的图书分类:\n");
	scanf("%s", book->arr[find].type);

	printf("请输入新的图书编号:\n");
	scanf("%s", book->arr[find].id);

	printf("修改成功!\n");
}

在指定位置之前删除数据

void SLErase(Book* book, int pos);
//在指定位置之前删除数据
void SLErase(Book* book, int pos)
{
	assert(book);//断言防止传入空指针

	//判断删除的数据是否合法
	if (pos >= 0 && pos < book->size)
	{
		// 删除数据
		for (int i = pos; i < book->size - 1; i++)
		{
			book->arr[i] = book->arr[i + 1];//ps->[size-2]=ps->arr[size-1]
		}
		--book->size;
	}
}

 书籍查找展示数据

void BookFind(Book* book);
//查找图书数据
void BookFind(Book* book)
{
	char name[BOOKNAME];
	printf("请输入你要查找的书籍名字:\n");
	scanf("%s", name);

	//检查图书数据是否存在
	int find = FindByName(book, name);
	if (find < 0)
	{
		printf("您要查找的书籍不存在!\n");
		return;
	}
	// 1.书名  2.作者  3.价格  4.分类  5.编号
	printf("%-10s %-10s %-10s %-10s %-15s\n", "书名", "作者", "价格", "分类", "编号");
	printf("-------------------------------------------------------------\n");
	//找到了
	printf("%-10s %-10s %-10.1f %-10s %-15s\n",
		book->arr[find].book_name,
		book->arr[find].author,
		book->arr[find].price,
		book->arr[find].type,
		book->arr[find].id
	);
}

 测试文件:

#define _CRT_SECURE_NO_WARNINGS 1
#include "BookList.h"
#include <windows.h>

enum book_name
{
	ExitBook, // 0
	AddBook, // 1
	DelBook, //...
	PrintBook,
	ChangeBook,
	CheckBook
};

void book_print()
{
	printf("*****************书籍录*********************\n");
	printf("*************1. 增添图书********************\n");
	printf("*************2. 删除图书********************\n");
	printf("*************3. 打印图书********************\n");
	printf("*************4. 修改图书********************\n");
	printf("*************5. 查找图书********************\n");
	printf("*************0. 退出图书录******************\n");
}

int main()
{
	Book b1;// 创建通讯录对象,实际上就是顺序表对象,等价于 SL sl
	 //顺序表的创建
	BookInit(&b1);

	int op = -1;
	do
	{
		book_print();
		printf("请选择你的操作:\n");
		scanf("%d", &op);
		switch (op)
		{
		case ExitBook:
			printf("退出图书录系统...\n");
			Sleep(1000);
			break;
		case AddBook:
			BookAdd(&b1);
			Sleep(1000);
			break;
		case DelBook:
			BookDel(&b1);
			Sleep(1000);
			break;
		case PrintBook:
			BookPint(&b1);
			Sleep(1000);
			break;
		case ChangeBook:
			BookModify(&b1);
			Sleep(1000);
			break;
		case CheckBook:
			BookFind(&b1);
			Sleep(1000);
			break;
		default:
			printf("选择错误,请重新选择\n");
			Sleep(1000);
			break;
		}
	} while (op != 0);


	// 顺序表的销毁
	BookDestroy(&b1);

	return 0;
}

 源代码文件:

BookList_2024_4_5 · 34c38d2 · 阳区欠/C语言学习路程 - Gitee.com

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LogicFlow 在HTML中的引入与使用

LogicFlow 在HTML中的引入与使用 LogicFlow的引入与使用&#xff0c;相较于BPMNJS相对容易一些&#xff0c;更加灵活一些&#xff0c;但是扩展代码可能写得更多一些。 示例展示 使用方式 这个的使用方式就简单很多了&#xff0c;利用cdn把js下载下来&#xff0c;引入到HTML文…

Python爬虫-懂车帝新能源汽车近一年销量榜

前言 本文是该专栏的第24篇,后面会持续分享python爬虫干货知识,记得关注。 笔者在本专栏之前,有详细介绍以“懂车帝平台的新能源汽车销量榜单”为例,获取各车型的销量排行榜单数据。而本文,笔者将单独详细来介绍如何获取“近一年的新能源汽车销量榜单”数据。 具体实现思…

信创(统信)系统上的软件安装及软件使用手册

一.各软件的安装文档 1.达梦数据库在统信系统上的安装 官方手册:https://eco.dameng.com/document/dm/zh-cn/start/install-dm-linux-prepare.html 1.1下载安装包 官网:https://www.dameng.com/list_103.html 点击”服务与合作”--> “下载中心” 这里选择对应的cpu和操作…

#include<初见c语言之字符函数和字符串函数>

目录 一、字符分类函数 二、字符转换函数 三、strlen的使⽤和模拟实现 1.strlen使用 2.strlen函数的模拟实现 四、 strcpy的使⽤和模拟实现 1.strcpy使用 2.strcpy函数的模拟实现 五、strcat的使用和模拟实现 1.strcat的使用 2.strcat的模拟实现 六、strcmp的使用…

【HTML】CSS样式(二)

上一篇我们学习了CSS基本样式和选择器&#xff0c;相信大家对于样式的使用有了初步认知。 本篇我们继续来学习CSS中的扩展选择器及CSS继承性&#xff0c;如何使用这些扩展选择器更好的帮助我们美化页面。 下一篇我们将会学习CSS中常用的属性。 喜欢的 【点赞】【关注】【收藏】…

214基于matlab的交互多模算法(IMM)机动目标跟踪算法

基于matlab的交互多模算法&#xff08;IMM&#xff09;机动目标跟踪算法&#xff0c;完整的15页文档论文。根据二维空间内目标作匀速直线运动和匀速圆周运动的特点&#xff0c;在建立目标运动模型和观测模型的基础上采用基于交互多模算法&#xff08;IMM&#xff09;的卡尔曼滤…

MySQL 50 道查询题汇总,足以巩固大部分查询(附带数据准备SQL、题型分析、演示、50道题的完整SQL)

目录 MySQL 50 道查询题&#xff0c;足以巩固大部分查询数据准备&#xff1a;创建表sql添加表数据sql 50道查询题目汇总01 - 05 题&#xff1a;1、查询 “01” 语文成绩比 “02” 数学成绩高的学生的信息及课程分数2、查询 "01语文课程"比"02数学课程"成绩…

ARM架构学习笔记2-汇编

RISC是精简指令集计算机&#xff08;RISC:Reduced Instruction Set Computing&#xff09; ARM汇编概述 一开始&#xff0c;ARM公司发布两类指令集&#xff1a; ① ARM指令集&#xff0c;这是32位的&#xff0c;每条指令占据32位&#xff0c;高效&#xff0c;但是太占空间 2…

0基础学习Mybatis系列数据库操作框架——自定义类型处理器

大纲 Java模型类定义类型处理器配置文件和类型绑定和字段绑定resultMap中绑定 Mapper代码测试类型对应关系表总结参考资料 我们有时候会在数据库中放入一个扩展字段&#xff0c;用于保存在表设计时尚未考虑到的、未来会加入的一些信息。这个字段我们一般使用字符串存储&#xf…

短视频素材高清无水印购买要多少钱?

大家好&#xff01;在制作短视频时&#xff0c;找到短视频素材高清无水印是非常重要的。那么&#xff0c;短视频素材高清无水印在哪里找呢&#xff1f;今天&#xff0c;我要给大家推荐六个主流的视频素材分享网站&#xff0c;帮助你轻松获取高质量的短视频素材高清无水印&#…

C++读取.bin二进制文件

C读取.bin二进制文件 在C中&#xff0c;可以使用文件输入/输出流来进行二进制文件的读写操作&#xff0c;方便数据的保存和读写。 //C读取bin二进制文件 int read_bin() {std::ifstream file("data_100.bin", std::ios::in | std::ios::binary);if (file) {// 按照…

Hive初始化元数据库(默认是derby数据库)时候出现缺少方法的错误com.google.common.base.Preconditions

错误的出现&#xff1a; 下载好hive后&#xff0c;初始化元数据库&#xff08;使用内置derby数据测试&#xff09;&#xff0c;出现报错 初始化hive元数据&#xff1a;schematool -dbType derby -initSchema 这个原因是与 Hive 和 Hadoop 版本的 Guava 版本不一样导致的。 解决…

SpringBoot+ECharts+Html 字符云/词云案例详解

1. 技术点 SpringBoot、MyBatis、thymeleaf、MySQL、ECharts 等 2. 准备条件 在mysql中创建数据库echartsdb&#xff0c;数据库中创建表t_comment表&#xff0c;表中设置两个字段word与count&#xff0c;添加表中的数据。如&#xff1a;附件中的 echartsdb.sql 3. SpringBoot…

webrtcP2P通话流程

文章目录 webrtcP2P通话流程webrtc多对多 mesh方案webrtc多对多 mcu方案webrtc多对多 sfu方案webrtc案例测试getUserMediagetUserMedia基础示例-打开摄像头getUserMedia canvas - 截图 打开共享屏幕 webrtcP2P通话流程 在这里&#xff0c;stun服务器包括stun服务和turn转发服…

Aurora8b10b(1)IP核介绍并基于IP核进行设计

文章目录 前言一、IP核设置二、基于IP核进行设计2.1、设计框图2.2、aurora_8b10b_0模块2.3、aurora_8b10b_0_CLOCK_MODULE2.4、aurora_8b10b_0_SUPPORT_RESET_LOGIC2.5、aurora8b10b_channel模块2.6、IBUFDS_GTE2模块2.7、aurora_8b10b_0_gt_common_wrapper模块2.8、aurora8b10…

多路转接-epoll/Reactor(2)

epoll 上次说到了poll&#xff0c;它存在效率问题&#xff0c;因此出现了改进的poll----epoll。 目前epoll是公认的效率最高的多路转接的方案。 快速了解epoll接口 epoll_create&#xff1a; 这个参数其实已经被废弃了。 这个值只要大于0就可以了。 这是用来创建一个epoll模…

阿里云服务器资费:一年或1个月费用价格,2024年更新

阿里云服务器资费多少钱&#xff1f;一年或1个月费用价格&#xff1a;2核2G3M轻量服务器61元一年、ECS云服务器2核2G3M 99元一年&#xff0c;2核4G轻量165元一年&#xff0c;2核4G ECS 199元一年&#xff0c;阿里云服务器网aliyunfuwuqi.com整理如下&#xff1a; 1、ECS经济型e…

SpringBoot快速入门笔记(4)

文章目录 一、Vue框架1、前端环境准备2、简介3、快速开始4、事件绑定 二、Vue组件化开发1、NPM2、Vue Cli3、组件化开发4、SayHello自定义组件5、Movie自定义组件 一、Vue框架 1、前端环境准备 编码工具&#xff1a;VSCode 依赖管理&#xff1a;NPM 项目构建&#xff1a;VueCl…

Word·VBA文档合并

目录 1&#xff0c;复制法&#xff0c;不保留原文档格式2&#xff0c;复制法&#xff0c;保留原文档格式3&#xff0c;插入法&#xff0c;保留原文档格式 之前的文章《WordVBA实现邮件合并》虽然可以生成邮件合并文档结果&#xff0c;但是不能像《python实现word邮件合并》一样…

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】

LeetCode-79. 单词搜索【数组 字符串 回溯 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;回溯 回溯三部曲。这里比较关键的是给board做标记&#xff0c;防止之后搜索时重复访问。解题思路二&#xff1a;回溯算法 dfs,直接看代码,很容易理解。visited哈希&#xff0c;防止…