C语言餐厅管理系统
做好事不留名_ 人气:0在学习完C语言之后,写了一个小程序,涉及到单链表,文件,排序,等内容。
这个对新手指针,函数等方面的掌握有一定的要求。
一.程序开始界面
1.输入不同的数字,选择你要的操作,进行点菜,修改账单,结算等功能
2.热卖推荐中会默认打印当前餐厅热卖的各类食物排行前三位(可以自己选择查看前几位,因为懒,就没加这个功能,要加入这个功能,简单改一下就行)
3.输入0结算,系统会打印出菜单,并将数据以xls表格形式存到后台
二.点餐页面
1.此时我们选择凉菜类
2.选完后会打印出已选择菜单,并提示是否修改
三.后台文件
1.程序的菜类文件(名字 价格 销售量)都存于后台文件中。使用管理员登陆可以对其进行修改,删除,添加等操作
2.每等一个用户下单,程序都会对后台菜类文件对应的销售额进行调整,并在下一次使用程序时对其排序,以选出销量高的菜品
3.用户下单后生成的账单也会储存于后台(.xls)
以下是程序源代码:
#include<stdio.h> #include<stdlib.h> #include<io.h> #include<string.h> #include<time.h> #define PATH "C:\\Users\\14765\\Desktop\\点餐系统" //餐厅点餐程序 float SUM=0; //消费总计 FILE *CheckBills; //账单 char date[80]; //账单编号 typedef struct Food{//销量 char name[50]; float price; int sales; }FOOD; typedef struct Bill{ char name[30]; float price; int num; int sign; int sign_num; struct Bill *next; }BILL; typedef struct Dishes{ char name[30]; float price; int sales; struct Dishes *next; }DISH; void printMenu(){//选择界面 printf(" ----------------------- \n"); printf(" | 菜单 | \n"); printf(" ----------------------- \n"); printf(" | 1.热卖推荐 | \n"); printf(" ----------------------- \n"); printf(" | 2.凉菜 | \n"); printf(" ----------------------- \n"); printf(" | 3.热菜 | \n"); printf(" ----------------------- \n"); printf(" | 4.饮品 | \n"); printf(" ----------------------- \n"); printf(" | 5.特产小吃 | \n"); printf(" ----------------------- \n"); printf(" | 6.吃遍中国系列 | \n"); printf(" ----------------------- \n"); printf(" | 0.退出并结算 | \n"); printf(" ----------------------- \n"); printf("\n"); } void printDishes(FILE *fp){//打印菜单文件数据 char name[20]; float price; int count=1; int a;//销量 while(fscanf(fp,"%s%f%d",name,&price,&a)!=EOF){ getc(fp); printf("%2d.%-15s %.1f\n",count++,name,price); } rewind(fp); } void reviseDish(FILE *fp){//修改菜名,价格... int snum; char cName[15]; float price; printf("1.修改名称\n2.修改价格\n"); do{ scanf("%d",&snum); }while(snum!=1&&snum!=2); if(snum==1){ printf("请输入要修改的名称:\n"); scanf("%s",cName); fprintf(fp,"%-15s",cName); }else{ printf("请输入要修改的价格:\n"); scanf("%f",&price); fseek(fp,16,1); fprintf(fp,"%4.1f",price);//这儿应该有一个判断格式的函数,确保其输入到文件的格式(已解决) } rewind(fp); } void printDishL(DISH *dish){//打印菜单(链表) DISH *temp=dish; int count=1; while(temp!=NULL){ printf("%2d.%-15s%.1f\n",count++,temp->name,temp->price); temp=temp->next; } } //先把管理部分做了 void reviseMenuDetail(char *setName){//修改菜单函数(具体实现) FILE *fp; int a; if((fp=fopen(setName,"r+"))==NULL){ printf("Error!\n"); exit(1); } B: printf("请选择:\n1.添加菜品\n2.删除菜品\n3.修改菜品\n0.退出\n"); scanf("%d",&a); switch(a){ case 1:{ fp=fopen(setName,"a+"); while(1){ char name[30],c; float price; printf("请依次输入菜名,价格:\n"); scanf("%s %f",name,&price); fprintf(fp,"%-15s %4.1f%5d\n",name,price,0); printf("是否继续录入?(Y or N)\n"); do{ scanf("%c",&c); }while(c!='Y'&&c!='N'); if(c=='N'){ break; } } fclose(fp); goto B; } case 2:{ int snum; fp=fopen(setName,"r+"); char name[30]; float price; int sales; DISH *dishes=NULL,*temp=NULL,*r; while(fscanf(fp,"%s %f%d\n",name,&price,&sales)!=EOF){ r=(DISH*)malloc(sizeof(DISH)); strcpy(r->name,name); r->price=price; r->sales=sales; // printf("%-15s%.1f\n",name,price); if(dishes==NULL){ temp=r; dishes=temp; r->next=NULL; }else{ temp->next=r; temp=temp->next; r->next=NULL; } } rewind(fp); printf("请选择删除的内容:(输入-1退出)\n"); printDishes(fp); while(1){ scanf("%d",&snum); if(snum==-1){ break; } DISH *tp=dishes,*t=NULL,*t1=NULL; for(int i=1;i<snum;i++){ t=tp; tp=tp->next; } if(t==NULL){ t=dishes; dishes=dishes->next; free(t); }else{ t1=tp; t->next=tp->next; free(t1); } printDishL(dishes); } fp=fopen(setName,"w+"); temp=dishes; while(temp!=NULL){ strcpy(name,temp->name); price=temp->price; fprintf(fp,"%-15s %.1f%5d\n",name,price,temp->sales); temp=temp->next; } printf("删除完成!\n"); fclose(fp); // fseek(fp,22*(snum-1),0); goto B; } case 3:{ int snum; B1: fp=fopen(setName,"r+"); printf("请选择修改的内容:\n"); printDishes(fp); fseek(fp,0,2); int f=ftell(fp); int flimit=f/27; rewind(fp); scanf("%d",&snum); if(snum>flimit){ printf("请输入正确的数字!\n"); goto B1; } fseek(fp,27*(snum-1),0); reviseDish(fp); char c; printf("是否继续修改?(Y or N)\n"); do{ scanf("%c",&c); }while(c!='Y'&&c!='N'); if(c=='Y'){ goto B1; } fclose(fp); goto B; } case 0:{ break; } default:{ goto B; } } } void reviseMenu(){//修改菜单函数(方法) char password[30]; printf("请输入管理员密码:\n"); scanf("%s",&password); if(!strcmp(password,"520521")){ printf("登录成功!\n"); }else{ printf("密码错误!"); return; } int num; A: printf("请选择修改的菜类:(0退出后台管理系统)\n"); scanf("%d",&num); switch(num){ case 1:{ printf("此选项不可更改,请重新选择\n"); goto A; } case 2:{ char a[]="凉菜.txt"; reviseMenuDetail(a); goto A; } case 3:{ char a[]="热菜.txt"; reviseMenuDetail(a); goto A; } case 4:{ char a[]="饮品.txt"; reviseMenuDetail(a); goto A; } case 5:{ char a[]="特产小吃.txt"; reviseMenuDetail(a); goto A; } case 6:{ printf("尚未开放!\n"); goto A; } case 0:{ break; } default:{ printf("请重新输入!\n"); goto A; } } } void printBill(BILL *bill,char *dname){ BILL *temp=bill; printf("—————————————%s—————————————\n",dname); float sum=0; int count=1; while(temp!=NULL){ printf("|No.%d.%-15s%d(份) * %.1f(元) 小计: %.1f(元)|\n",count++,temp->name,temp->num,temp->price,temp->num*temp->price); printf("————————————————————————————\n"); sum+=temp->price*temp->num; temp=temp->next; } printf(" 共计: %.1f(元)\n",sum); } void reviseBill_D(BILL **bill,int n){//(***) BILL *temp,*r=NULL,*r0=NULL; if(n==1){ temp=*bill; *bill=(*bill)->next; free(temp); }else{ int i=1; r=*bill; while(i<n){ r0=r; r=r->next; temp=r->next; i++; } free(r); r0->next=temp; } } void revise_sales(FILE *fp,int num,int salenum,int aa){ fseek(fp,27*(num-1),0); fseek(fp,20,1); fprintf(fp,"%5d",aa+salenum); } void reviseBill(BILL **bill_,FILE *fp){ //修改账单 ——————————要点(***) int snum,num=0,snum1,snum2; BILL *bill=*bill_; while(1){ BILL *temp=bill,*r; while(temp!=NULL){ num++; //num为链表内容数目 temp=temp->next; } printf("请选择修改的菜品(序号) 输入0退出:\n"); scanf("%d",&snum); if(snum>0&&snum<=num){ r=bill; int i=1; while(i<snum){ r=r->next; //目标菜品 i++; } printf("1.修改数量 2.删除该菜品 0.返回\n"); do{ scanf("%d",&snum1); if(snum1==0){ break; } }while(snum1!=1&&snum1!=2); if(snum1==1){ printf("请输入要修改的数量:\n"); scanf("%d",&snum2); if(snum2==0){ reviseBill_D(bill_,snum); }else{ r->num=snum2; } }else if(snum1==2){ reviseBill_D(bill_,snum); } }else if(snum==0){ break; }else{ printf("请重新输入!\n"); } num=0; revise_sales(fp,r->sign,r->num,r->sign_num); rewind(fp); } } void checkDishes(FILE *fp,char *dName,char *dname){ int s,num,num1,aa; BILL *bill=NULL,*temp,*r; if((fp=fopen(dName,"r+"))==NULL){ printf("系统错误,请联系工作人员"); exit(1); } printf("请选择菜品和数量(用空格分开):(输入0返回)\n"); printDishes(fp); fseek(fp,0,2); num=ftell(fp)/27; char name[30]; float price; while(1){ //账单用链表来做 rewind(fp); scanf("%d",&s); if(s==0){ break; } scanf("%d",&num1); if(s<=num&&s>0){ fseek(fp,27*(s-1),0); fscanf(fp,"%s%f%d",name,&price,&aa); r=(BILL *)malloc(sizeof(BILL)); strcpy(r->name,name); r->price=price; r->num=num1; r->sign=s;//链表带着菜在文件中的顺序 r->sign_num=aa; if(bill==NULL){ bill=r; temp=bill; }else{ temp->next=r; temp=temp->next; } r->next=NULL; printf("名称:%s 价格:%.1f 数量:%d\n",name,price,num1); }else{ printf("请重新选择.\n"); continue; } rewind(fp); revise_sales(fp,s,num1,aa); } rewind(fp); printBill(bill,dname); char c; while(1){ printf("是否对已选菜品进行修改?(Y or N)\n"); do{ scanf("%c",&c); }while(c!='Y'&&c!='N'); if(c=='Y'){ reviseBill(&bill,fp); printBill(bill,dname); }else{ break; } } // if((CheckBills=fopen(date,"a+"))==NULL){ // printf("Error!"); // exit(1); // } //bill为目前账单链表,dname为菜系 //先获取最后选择菜的数量 int num_1=0,_count=1; BILL *temp1=bill,*temp2=bill; while(temp1!=NULL){ num_1++; temp1=temp1->next; } float _sum=0; fprintf(CheckBills,"\t\t%s类\n",dname); fprintf(CheckBills,"序号\t 品名 \t单价(元/份)\t数量\t小计\n");// \n为换行符\r为回车符 for(int i=0;i<num_1;i++){ fprintf(CheckBills," %d \t%s\t %.1f \t %d \t%.1f(元)\n",_count++,temp2->name,temp2->price,temp2->num,temp2->num*temp2->price); _sum+=temp2->num*temp2->price; temp2=temp2->next; } SUM+=_sum; fprintf(CheckBills,"\t\t\t共计:\t%.1f(元)\n",_sum); } void check_out(){//结账 fprintf(CheckBills,"\t\t\t消费合计: %.1f(元)",SUM); } void sellB(FILE *fp,DISH **dp,int *n){//录入数据到链表 char s[30];float p;int sales; DISH *r,*temp; int n1=0; while(fscanf(fp,"%s%f%d",s,&p,&sales)!=EOF){ r=(DISH *)malloc(sizeof(DISH)); strcpy(r->name,s); r->sales=sales; r->price=p; r->next=NULL; if(*dp==NULL){ temp=r; *dp=r; }else{ temp->next=r; temp=temp->next; } n1++; } rewind(fp); *n=n1; // printf("ceshi"); } void sort(DISH *dp,int n,int *a){//将菜类的销量前五名在链表中的位置录入到数组 DISH *t=dp; int b[n];//销量数列 for(int i=0;i<n;i++){ b[i]=t->sales; t=t->next; } for(int i=0;i<n;i++){ int max=i; for(int j=i;j<n;j++){ if(b[j]>b[max]){ max=j; } } a[i]=max+1; b[max]=0; } } void printSells(DISH *dp,char *name,int *a){ DISH *temp=dp; printf("%s类\n",name); for(int i=0;i<3;i++){ for(int j=0;j<a[i]-1;j++){ temp=temp->next; } printf("No.%d %s",i+1,temp->name); if(i==2){ break; } printf("\n"); temp=dp; } printf("\n"); } void sellBriskly(){//热卖 FILE *fp,*fp1,*fp2,*fp3; if((fp=fopen("凉菜.txt","r"))==NULL){ printf("Error!\n"); exit(1); } if((fp1=fopen("热菜.txt","r"))==NULL){ printf("Error!\n"); exit(1); } if((fp2=fopen("饮品.txt","r"))==NULL){ printf("Error!\n"); exit(1); } if((fp3=fopen("特产小吃.txt","r"))==NULL){ printf("Error!\n"); exit(1); } DISH *d=NULL,*d1=NULL,*d2=NULL,*d3=NULL;//数据链表 int n,n1,n2,n3; sellB(fp,&d,&n);//文件,待录入链表,链表长度 sellB(fp1,&d1,&n1); sellB(fp2,&d2,&n2); sellB(fp3,&d3,&n3); DISH *temp=d1; int a[n]={0},a1[n1]={0},a2[n2]={0},a3[n3]={0}; sort(d,n,a);//目标链表,长度,待录入数组。 sort(d1,n1,a1); sort(d2,n2,a2); sort(d3,n3,a3); printf("————销量排行————\n"); char c[]="凉菜",c1[]="热菜",c2[]="饮品",c3[]="特产小吃"; printSells(d,c,a); printSells(d1,c1,a1); printSells(d2,c2,a2); printSells(d3,c3,a3); } int main(void){//可以设置一个管理员密码 printf("—————欢迎光临 西邮中餐厅—————\n\n"); printMenu(); int sNum; time_t t; time(&t); char str[64],str1[64]; strftime(str,sizeof(str),"%Y-%m-%d %H:%M:%S",localtime(&t)); //在文件命名时要注意部分英文字符不能用 strcpy(str1,str); strcat(str,".xls"); strcpy(date,str); if((CheckBills=fopen(date,"a+"))==NULL){ printf("Error!\n"); exit(1); } fprintf(CheckBills,"\t %s 消费记录\n",str1); A: printf("请选择菜类:(输入0结算)\n"); scanf("%d",&sNum); FILE *fp; BILL *bill=NULL; switch(sNum){ case 1:{//热卖推荐,要随着顾客点菜进行数据更新 sellBriskly(); goto A; } case 2:{//计算菜的数目:1.flength(fno)/一行字节数 2.遍历 char dname[]="凉菜"; char dName[]="凉菜.txt"; checkDishes(fp,dName,dname); goto A; } case 3:{ char dname[]="热菜"; char dName[]="热菜.txt"; checkDishes(fp,dName,dname); goto A; } case 4:{ char dname[]="饮品"; char dName[]="饮品.txt"; checkDishes(fp,dName,dname); goto A; } case 5:{ char dname[]="特产小吃"; char dName[]="特产小吃.txt"; checkDishes(fp,dName,dname); goto A; } case 6:{ printf("尚未开放!\n"); goto A; } case 0:{ check_out(); break; } case -1:{ reviseMenu(); return 0; } default:{ printf("请重新输入."); goto A; } } //fclose为什么会错?? OK! fclose(CheckBills); FILE *fp1; if((fp1=fopen(date,"r+"))==NULL){ printf("Error!"); exit(1); } char stre[100]; while(fgets(stre,100,fp1)!=NULL){ printf("%s",stre); } printf("\n————感谢惠顾,期待您下次光临!————"); }
加载全部内容