本文实例为大家分享了C语言单链表实现图书管理系统的具体代码,供大家参考,具体内容如下
单链表实现的图书管理系统相比于结构体实现的管理系统,可以随时开辟新的空间,可以增加书的信息
单链表的实现首先肯定还是打印单链表的常规操作,创建表头,创建节点,表头法插入,特定位置删除,打印链表
struct book
{
char name[20];
float price;
int num; //书的数量
};
//3 数据容器——链表
struct Node
{
struct book data;
struct Node*next;
};
void printflist(struct Node*headnode);
struct Node*headnode = NULL;
//创建表头
struct Node*createlisthead()
{
//动态内存申请
struct Node*headnode = (struct Node*)malloc(sizeof(struct Node));
//变量的基本规则:使用前必须初始化
headnode->next = NULL;
return headnode;
}
//创建节点,为插入做准备
//把用户的数据变为结构体变量
struct Node* createnewnode(struct book data)
{
struct Node*newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
//表头法插入
void insertbyhead(struct Node*headnode, struct book data)
{
struct Node* newnode = createnewnode(data);
//必须先连后断
newnode->next = headnode->next;
headnode->next = newnode;
}
//指定位置删除
void deletenodebyname(struct Node*headnode, char *bookname)
{
struct Node*posleftnode = headnode;
struct Node*posnode = headnode->next;
//字符串比较函数
while (posnode != NULL && strcmp(posnode->data.name,bookname))
{
posleftnode = posnode;
posnode = posnode->next;
}
//讨论结果
if (posnode == NULL)
{
printf("未找到数据");
return ;
}
else
{
posleftnode->next = posnode->next;
free(posnode);
posnode = NULL;
}
printflist(headnode);
}
//查找书籍
struct Node*searchbyname(struct Node*headnode, char *bookname)
{
struct Node *posnode = headnode->next;
while (posnode != NULL &&strcmp(posnode->data.name, bookname))
{
posnode = posnode->next;
}
return posnode;
}
//打印链表——从第二个节点开始打印
void printflist(struct Node*headnode)
{
struct Node* pmove = headnode->next;
printf("书名\t价格\t数量\n");
while (pmove!=NULL)
{
printf("%s\t%.1f\t%d\n", pmove->data.name,pmove->data.price,pmove->data.num );
pmove = pmove->next;
}
printf("\n");
}
冒泡排序——通过价格
第一个for循环表示遍历次数,第二个for循环使相邻的两个元素进行比较并交换
1 比较条件里,只用q指针即可
2 交换时需要创建一个临时变量
//冒泡排序算法
void bubblesortlist(struct Node*headnode)
{
for (struct Node*p = headnode->next; p != NULL; p = p->next)
{
for (struct Node*q = headnode->next; q->next != NULL; q = q->next)
{
if (q->data.price > q->next->data.price)
{
//交换
struct book tempdata = q->data;
q->data = q->next->data;
q->next->data = tempdata;
}
}
}
printflist(headnode);
}
如果不储存信息,那么每次在输入信息完毕后关闭控制台,信息无法保留,所以我们通过文件的方式来储存信息
文件写操作
1 通过创建节点指针变量来遍历输出文件中的信息
2 通过fprintf可以将输入的信息保持下来
//写操作
void savefile(const char*filename, struct Node*headnode)
{
FILE*fp = fopen(filename, "w");
struct Node*pmove = headnode->next;
while (pmove != NULL)
{
fprintf(fp, "%s\t%.1f\t%d\n", pmove->data.name, pmove->data.price, pmove->data.num);
pmove = pmove->next;
}
fclose(fp);
fp = NULL;
}
文件读操作
1 当用 “r”的形式打开文件失败时,说明没有此文件,则可以用“w+”的形式打开,当没有文件时,会创建一个文件
2 把读取出的数据以表头法插入到链表中则可以再次打印出信息
//文件读操作
void readfile(const char *filename, struct Node*headnode)
{
FILE*fp = fopen(filename, "r");
if (fp == NULL)
{
//不存在文件则创建
fp = fopen(filename, "w+");
}
struct book tempdata;
while (fscanf(fp, "%s\t%f\t%d\n", tempdata.name, &tempdata.price, &tempdata.num) != EOF)
{
insertbyhead(headnode, tempdata);
}
fclose(fp);
fp = NULL;
}
剩余代码
1 当查找书籍时先用临时指针接受找到书籍的指针,然后再打印书籍信息
//1 界面
void menu()
{
printf("---------------------------------\n");
printf("\t图书管理系统\n");
printf("\t0.退出系统\n");
printf("\t1.登记书籍\n");
printf("\t2.浏览书籍\n");
printf("\t3.借阅书籍\n");
printf("\t4.归还书籍\n");
printf("\t5.书籍排序\n");
printf("\t6.删除书籍\n");
printf("\t7.查找书籍\n");
printf("---------------------------------\n");
printf("请输入0~7\n");
}
//2 做交互
void keydown()
{
int input = 0;
struct book tempbook; //创建临时变量,存储书籍信息
struct Node*result = NULL; //创建临时指针变量,指向查找书籍的节点
scanf("%d", &input);
switch (input)
{
case 0:
printf("【退出】\n");
printf("退出成功\n");
system("pause");
exit(0); //关闭整个程序
break;
case 1:
printf("【登记】\n");
printf("输入书籍的信息(name,price,num)");
scanf("%s%f%d", tempbook.name, &tempbook.price, &tempbook.num);
insertbyhead(headnode, tempbook);
savefile("book.txt", headnode);
break;
case 2:
printf("【浏览】\n");
printflist(headnode);
break;
case 3:
printf("【借阅】\n"); //书籍存在,数量-1
printf("请输入要借阅的书籍");
scanf("%s", tempbook.name);
result = searchbyname(headnode, tempbook.name);
if (result == NULL)
{
printf("没有相关书籍,无法借阅");
}
else
{
if (result->data.num > 0)
{
result->data.num--;
printf("借阅成功");
}
else
printf("无库存");
}
break;
case 4:
printf("【归还】\n"); //书记归还,数量+1
printf("请输入要归还的书籍");
scanf("%s", tempbook.name);
result = searchbyname(headnode, tempbook.name);
if (result == NULL)
printf("来源非法");
else
{
result->data.num++;
printf("书籍归还成功!");
}
break;
case 5:
printf("【排序】\n");
bubblesortlist(headnode);
savefile("book.txt", headnode);
break;
case 6:
printf("【删除】\n");
printf("输入要删除的书名");
scanf("%s", tempbook.name);
deletenodebyname(headnode, tempbook.name);
savefile("book.txt", headnode);
break;
case 7:
printf("【查找】\n");
printf("请输入要查找的书籍");
scanf("%s", tempbook.name);
result = searchbyname(headnode, tempbook.name);
if (result == NULL)
{
printf("未找到相关信息!\n");
}
else
{
printf("书名\t价格\t数量\n");
printf("%s\t%.1f\t%d\t", result->data.name, result->data.price, result->data.num);
}
break;
default:
printf("选择错误,请重新选择:>");
break;
}
}
int main()
{
headnode = createlisthead();
readfile("book.txt", headnode);
while (1)
{
menu();
keydown();
system("pause");
system("cls");
}
system("pause");
return 0;
}