C语言图书管理系统
不可触碰的殇 人气:0单链表实现的图书管理系统相比于结构体实现的管理系统,可以随时开辟新的空间,可以增加书的信息
单链表的实现
首先肯定还是打印单链表的常规操作,创建表头,创建节点,表头法插入,特定位置删除,打印链表
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; }
加载全部内容