注意的点:
1.全局变量与局部变量,别再main里面再定义list,作用域不够长,传不到keyDown里面
假设有函数的功能是这样的:
readFile:读取记事本里面的内容让其到指针【fp】里面,再让fp把内容写道程序里面的变量存起来(fscanf可以实现),若没有该名字,则“w+”创建
writeToFile:·把程序里面的内容用指针(x)给到fp,再让fp写到记事本里面【fprintf可以实现】
2.文件操作:如何把记事本与控制台【终端】联系起来
关键:对list【全局变量,也是头指针的操作】,先把文件进行readFile操作(读取记事本里面的内容到程序),然后让读到的list进行链表操作完成功能模块,在进行writeToFile功能(把程序里面的内容写道记事本里面)
3.各个功能模块的本质:
0.退出系统:exit(0);
1.登记书籍:链表的插入【本人用的头插,这样不用找最后一个元素】
2.浏览书籍:链表的遍历
3.借阅书籍:链表内部成员的操作
4.归还书籍:同3
5.书籍排序:排序算法【本人冒泡】
6.删除书籍:链表的删除
7.查找书籍:字符串的比较与链表遍历
4.难点:结构体的相互引用。
5.模块化思想的展示。
/*图书管理系统*/
#include
#include
#include
typedef struct Book{
char name[20];
float price;
int num;
}Book;
typedef struct Node{
Book data;
struct Node* next;
}Node;
Node* list=NULL;
//创建表头
Node* createHead()
{
Node* headNode=(Node*)malloc(sizeof(Node));
headNode->next=NULL;
return headNode;
}
//创建结点
Node* createNode(Book data)
{
Node* newNode=(Node*)malloc(sizeof(Node));
newNode->data=data;
newNode->next=NULL;
return newNode;
}
//打印链表[case2]//
void Print(Node* headNode)
{
Node* pMove=headNode->next;
printf("书名\t价格\t数量\t\n");
while(pMove)
{
printf("%s\t%.1f\t%d\t\n",pMove->data.name,pMove->data.price,pMove->data.num);
pMove=pMove->next;
}
}
//表头法插入链表【头插法】
void insertHead(Node* headNode,Book data)
{
Node* newNode=(Node*)malloc(sizeof(Node));
newNode=createNode(data);
newNode->next=headNode->next;
headNode->next=newNode;
}
//读文件操作[把文件的内容读到结构体里面去fscanf]
void readFile(const char* fileName,Node* headName)//结合main里面的意义进行联系
{
FILE* fp = fopen(fileName,"r"); //fp直接读到了记事本里面的内容
if(!fp) fp=fopen(fileName,"w+");
Book tempData;
while(fscanf(fp,"%s\t%f\t%d\n",tempData.name,&tempData.price,&tempData.num)!=EOF)
{
insertHead(list,tempData);
}
fclose(fp);
}
//1.写界面,写菜单
void makeMenu()
{
printf("---------------------------\n");
printf(" 图书管理系统\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:");
}
//写文件【在记事本里面打印东西】 :[case1]
void writeToFile(const char* fileName,Node* headNode)
{
FILE* fp = fopen(fileName,"w");
Node* pMove=headNode->next;
while(pMove)
{
fprintf(fp,"%s\t%.1f\t%d\n",pMove->data.name,pMove->data.price,pMove->data.num);
pMove=pMove->next;
}
fclose(fp);
}
//冒泡排序 [case 5]
//以价格为参照标准
void bubbleSort(Node* headNode)
{
Book tempBook;
Node* pMove=headNode->next;
while(pMove->next)
{
if(pMove->data.price > pMove->next->data.price)
{
tempBook=pMove->data;
pMove->data=pMove->next->data;
pMove->next->data=tempBook;
}
pMove=pMove->next;
}
Print(headNode);
}
//指定位置删除[case 6]
void deleteName(Node* headNode,char* posBookName)
{
Node* pMove=headNode->next;
Node* leftMove=headNode;
while(strcmp(pMove->data.name,posBookName)&&pMove)
{
leftMove=pMove;
pMove=pMove->next;
}
if(!pMove)
{
printf("\n未找到对应结点。");
return ;
}else{
printf("\n删除成功");
leftMove->next=pMove->next;
free(pMove);
}
}
//查找书籍[case 7]
Node* searchByName(Node* headNode,char* bookName)
{
Node* pMove=headNode->next;
while(pMove)
{
if(!strcmp(pMove->data.name,bookName)&&pMove)
{
printf("\n找到了");
break;
}
pMove=pMove->next;
}
return pMove;
}
//2.交互按键处理跳转
void keyDown()
{
Node* result=NULL;
int userKey=0;
scanf("%d",&userKey);
Book tempBook; //产生一个临时变量在case 1 来存储书籍信息
switch (userKey)
{
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);
insertHead(list,tempBook);
writeToFile("bookInfor.txt",list);
break;
case 2:
printf("【浏览】\n");
printf("case1:list=%p\n",list);
Print(list);
break;
case 3:
printf("【借阅】\n"); //书籍存在,num-1
printf("\n请输入借阅的书名:");
scanf("%s",tempBook.name);
result=searchByName(list,tempBook.name);
if(!result)
{
printf("\n无该书籍无法借阅。");
}
else
{
if(result->data.num >= 1)
{
result->data.num--;
printf("\n借阅成功!");
}
else
{
printf("\n库存不足。");
}
}
break;
case 4:
printf("【归还】\n");
printf("\n请输入归还的书名:");
scanf("%s",tempBook.name);
result=searchByName(list,tempBook.name);
if(!result)
{
printf("\n馆内无此书。");
}
else
{
result->data.num++;
printf("\n书籍归还成功。");
}
break;
case 5:
printf("【排序】\n");
bubbleSort(list);
writeToFile("bookInfor.txt",list);
break;
case 6:
printf("【删除】\n");
printf("请输入要删除的书名:");
scanf("%s",tempBook.name);
deleteName(list,tempBook.name);
writeToFile("bookInfor.txt",list);
break;
case 7:
printf("【查找】\n");
printf("请输入查找书籍:");
scanf("%s",tempBook.name);
result=searchByName(list,tempBook.name);
if(!result) printf("\n未找到相关书籍!");
else
{
printf("\n书名\t价格\t数量\t\n");
printf("%s\t%.1f\t%d\n",result->data.name,result->data.price,result->data.num);
}
writeToFile("bookInfor.txt",list);
break;
default:
printf("【error】\n");
break;
}
}
int main(){
int i=0;
list=createHead();
readFile("bookInfor.txt",list); //只出现一次,创建
while(1)
{
makeMenu();
keyDown();
system("pause");
system("cls");
}
system("pause"); //防止闪停
return 0;
}