亲宝软件园·资讯

展开

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————感谢惠顾,期待您下次光临!————");
}

加载全部内容

相关教程
猜你喜欢
用户评论