目录
书籍存储的实现规划
编辑 前置准备:
书籍结构体:
书籍展示的初始化和文件加载
书籍展示的销毁和文件保存
书籍展示的容量检查
书籍展示的尾插实现
书籍展示的书籍增加
书籍展示的书籍打印
书籍删除展示数据
书籍展示修改数据
在指定位置之前删除数据
书籍查找展示数据
测试文件:
源代码文件:
书籍存储的实现规划
前置准备:
文件前置创建:
- BookList.h - 头文件声明
- BookList.c - 实现功能
- 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