自助点餐系统基本框架

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

float total_price = 0,today_price=0;
FILE *fp;

// 菜品数据结构
struct dish 
{
    char name[20];//菜品名称
    float price;//菜品单价
    int quantity;//菜品剩余数量
    int count;//用于记录销售数量
    struct dish *left;
    struct dish *right;
}records[100];

// 树结构体
struct tree 
{
    struct dish *root;
}t,hottree;//t用于存所有的菜品,hottree用于存热销菜品

// 初始化树
void init_tree(struct tree *t)
{
    t->root = NULL;
}

// 插入节点
void insert_node(struct dish *p, struct dish *n)//p为t
{
    if (strcmp(n->name, p->name) < 0) //按照字符串的大小来决定存储的顺序
    {
        if (p->left == NULL) 
        {
            p->left = n;
        } 
        else 
        {
            insert_node(p->left, n);
        }
    } 
    else 
    {
        if (p->right == NULL) 
        {
            p->right = n;
        } 
        else 
        {
            insert_node(p->right, n);
        }
    }
}

// 插入菜品
void add_dish(struct tree *t) 
{
    struct dish *new_dish = (struct dish*) malloc(sizeof(struct dish));
    printf("\t\t请输入菜品名称:");
    scanf("%s", new_dish->name);
    printf("\t\t请输入菜品价格:");
    scanf("%f", &new_dish->price);
    printf("\t\t请输入菜品数量:");
    scanf("%d", &new_dish->quantity);
    new_dish->count=0;
    new_dish->left = NULL;
    new_dish->right = NULL;
    if (t->root == NULL) 
    {
        t->root = new_dish;
    } 
    else 
    {
        insert_node(t->root, new_dish);
    }
    printf("\t\t菜品已成功添加\n\n");
}

// 将树按照中序的方式遍历并输出
void traverse_tree(struct dish *p) 
{
    if (p != NULL) 
    {
        traverse_tree(p->left);
        printf("\t\t%-12s\t单价:%-8.2f\t剩余储量%-10d\n", p->name, p->price,p->quantity);
        traverse_tree(p->right);
    }
}

// 显示菜单
void show_menu(struct tree *t) 
{
    if(t->root==NULL) 
    {
        printf("\t\t该店铺还暂未拥有菜单\n\n");
        return ;
    } 

    printf("\t\t\t      欢迎来到好运来餐厅!\n");
    printf("\t\t---------------------菜单---------------------\n");
    traverse_tree(t->root);
    printf("\t\t----------------------------------------------\n");
    printf("\n");
}

// 查找树的节点(查找树的里存的菜单)
struct dish *find_node(struct dish *p, char *name)
{
    if (p == NULL) 
    {
        return NULL;
    } 
    else if (strcmp(name, p->name) == 0)
    {
        return p;
    } 
    else if (strcmp(name, p->name) < 0)
    {
        return find_node(p->left, name);
    }
    else 
    {
        return find_node(p->right, name);
    }
}

// 查找菜品
void find_dish(struct tree *t) {
    char name[20];
    printf("\t\t请输入要查找的菜品名称:");
    scanf("%s", name);
    struct dish *result = find_node(t->root, name);
    if (result == NULL)
    {
        printf("\t\t未找到该菜品\n");
    } 
    else 
    {
        printf("\t\t菜品名称:%s,价格:%.2f元,数量:%d\n", result->name, result->price,result->quantity);
    }
}

// 修改菜品信息
void modify_dish(struct tree *t) 
{
    char name[20];
    printf("\t\t请输入要修改的菜品名称:");
    scanf("%s", name);
    struct dish *result = find_node(t->root, name);
    if (result == NULL) 
    {
        printf("\t\t未找到该菜品\n");
    } 
    else 
    {
        //将要修改的菜品名称与价格调整
        printf("\t\t请输入新的菜品名称:");
        scanf("%s", result->name);
        printf("\t\t请输入新的菜品价格:");
        scanf("%f", &result->price);
        printf("\t\t请输入新的菜品数量:");
        scanf("%d", &result->quantity);
        result->count=0;
        printf("\t\t菜品信息已成功修改\n");
    }
}

 //删除节点(将菜)
struct dish *delete_node(struct dish *p, char *name) 
{
    struct dish *temp;
    if (p == NULL) 
    {
        return NULL;
    } 
    else if (strcmp(name, p->name) < 0) 
    {
        p->left = delete_node(p->left, name);
    } 
    else if (strcmp(name, p->name) > 0)
    {
        p->right = delete_node(p->right, name);
    } 
    else //找到要删除的结点p了
    {
        if (p->left == NULL) 
        {
            temp = p->right;
            free(p);
            return temp;
        } 
        else if (p->right == NULL) 
        {
            temp = p->left;
            free(p);
            return temp;
        } 
        else //找到的菜品左右结点都不为空
        {
            temp = p->right;//指向p的右孩子
            while (temp->left != NULL) 
            {
                temp = temp->left;
            }
            strcpy(p->name, temp->name);
            p->price = temp->price;
            p->right = delete_node(p->right, temp->name);
        }
    }
    return p;
}

// 将菜品从"树"里删除
void delete_dish(struct tree *t) {
    char name[20];
    printf("\t\t请输入要删除的菜品名称:");
    scanf("%s", name);
    t->root = delete_node(t->root, name);
    printf("\t\t菜品已经成功删除\n\n");
}

// 计算账单
float calculate_bill(char order[20][20], int count, struct tree *t) 
{
    
    for (int i = 0; i < count; i++) 
    {
        struct dish *result = find_node(t->root, order[i]);
        if (result == NULL)
        {
            printf("\t\t%s不在菜单中\n", order[i]);
        } 
        else if(result->quantity<=0)
        {
            printf("\t\t%s的存库不够\n",order[i]);
        }
        else 
        {
            printf("\t\t已加入%s\t%.2f元\n", order[i], result->price);
            result->quantity--;
            total_price += result->price;
            result->count++;
        }
    }
    printf("\t\t总计:%.2f元\n", total_price);
    return total_price;
}

//将热销菜品存入树
void add_hotdish(struct tree *hottree,struct dish *result)
{
    struct dish *newhot_dish = (struct dish*) malloc(sizeof(struct dish));
    newhot_dish->left = NULL;
    newhot_dish->right = NULL;
    newhot_dish->price = result->price;
    newhot_dish->quantity = result->quantity;
    strcpy(newhot_dish->name,result->name);
    
    if (hottree->root == NULL) 
    {
        hottree->root = newhot_dish;
    } 
    else 
    {
        insert_node(hottree->root,newhot_dish);
    }
    
}

// 热推菜品
void hot_recommended() 
{
    int n;
    char name[20];
    printf("\t\t添加热推菜品回答1,删除热推菜品回答2\n\t\t");
    scanf("%d",&n);
    if(n==2)
    {
        printf("\t\t请输入要删除的菜品名称:");
        scanf("%s", name);
        hottree.root = delete_node(hottree.root, name);
        printf("\t\t热推菜品删除成功!\n");
        return ;
    }
    else if(n==1) 
    {
          printf("\t\t请输入要推荐的菜品名称:");
           scanf("%s", name);
        struct dish *result = find_node(t.root, name);
        if (result == NULL) 
        {
            printf("\t\t未找到该菜品\n");
        } 
        else 
        {
            add_hotdish(&hottree,result);
            printf("\t\t%s已成功加入热推菜单\n", name);
        }
    }
    else printf("\t\t输入错误\n");
}

// 点餐
void Ordering(struct tree *t) 
{
    char order[20][20]; // 一桌最多上20份菜
    int count = 0;
    printf("\t\t请点餐:\n");
    while (1) 
    {
        printf("\t\t请输入要点的菜品名称(按q结束):");
        char name[20];
        scanf("%s", name);
        if (strcmp(name, "q") == 0) 
        {
            break;
        } 
        else 
        {
            strcpy(order[count], name);//将菜名保存
            count++;
        }
    }
    if (count > 0) 
    {
        calculate_bill(order,count,t);    
    } 
    else
    {
        printf("\t\t你没有点任何菜品\n");
    }
}

//顾客结账
void checkout()
{
    printf("\t\t您一共消费%f元\n",total_price);
    printf("\t\t请输入支付金额:");
    float paid;
    scanf("%f", &paid);
    while (paid < total_price) 
    {
        printf("\t\t支付金额不足,请重新输入:");
        scanf("%f", &paid);
    }
    printf("\t\t找零:%.2f元\n", paid-total_price);
    today_price+=total_price;
    total_price=0;
    printf("\t\t结账完成,欢迎再次光临!\n");
}

//补充菜品的数量
void supplement()
{
    char name[20];//菜品名称
    int n;
    printf("\t\t请输入要补充菜品的名字:");
    scanf("%s",name);
    printf("\t\t请输入要补充菜品的数量:");
    scanf("%d",&n);
    struct dish *result = find_node(t.root, name);
    if (result == NULL)
    {
        printf("\t\t未找到该菜品\n");
    } 
    else 
    {
        result->quantity+=n;
        printf("\t\t菜品补充成功\n");
        printf("\t\t%s剩余储量为%d\n",name,result->quantity);
    }
}

//统计一次运行的总营销额度
void today_bill()
{
    printf("\t\t今日总营销额度为%.2f元\n",today_price);
}

//希尔排序
void shell_sort(struct dish arr[], int n) 
{
    int gap, i, j;
    struct dish temp;
    for (gap = n / 2; gap > 0; gap /= 2)
    {
        for (i = gap; i < n; i++) 
        {
            temp = arr[i];
            for (j = i; j >= gap && arr[j - gap].count <temp.count; j-=gap) 
            {
                arr[j] = arr[j - gap];
            }
            arr[j] = temp;
        }
    }
}

// 按销售额由大到小排序
void sort_sales_records(struct dish records[], int index) 
{
    if(index==0) 
    {
        printf("\t\t还拥有菜单,无销售额\n");
    }
    shell_sort(records,index);
    
}

//将二叉树里的菜品暂时存储在数组
void sales_rank(struct dish *t,struct dish records[],int *index)
{
    if (t) 
    {
        sales_rank(t->left, records, index);
        records[(*index)++] = *t;
        sales_rank(t->right, records, index);
    }
}

//按照销售额输出
void print(int index)
{
    printf("\t\t***********************************\n");
    printf("\t\t销售排行榜:\n");
    for(int i=0;i<index;i++)
    printf("\t\t%-20s%d\n",records[i].name,records[i].count);
    printf("\t\t***********************************\n");
}

//管理员的操作选项函数
void manageDishes()
{
    while (1) 
    {
        int option;
        printf("\t\t======================");
        printf("\n\t\t请选择:\n");
        printf("\t\t[1] 增加菜品\n");
        printf("\t\t[2] 查找菜品\n");
        printf("\t\t[3] 修改菜品信息\n");
        printf("\t\t[4] 删除菜品\n");
        printf("\t\t[5] 显示菜单\n");
        printf("\t\t[6] 热推菜品\n");
        printf("\t\t[7] 补菜数量\n");
        printf("\t\t[8] 查看一天销售额统计\n");
        printf("\t\t[9] 查看菜品销售排行榜\n");
        printf("\t\t[10] 退出\n");
        printf("\t\t======================\n\t\t");
        scanf("%d", &option);
        if(option==10) break;
        switch (option) 
        {
            case 1:
                add_dish(&t);
                break;
            case 2:
                find_dish(&t);
                break;
            case 3:
                modify_dish(&t);
                break;
            case 4:
                delete_dish(&t);
                break;
            case 5:
                show_menu(&t);
                break;
            case 6:
                hot_recommended();
                break;
            case 7://补菜的
                supplement();
                break;
            case 8://统计一次运行程序的总营业额
                today_bill();
                break;
            case 9://统计每一天菜品销售排行榜
                {
                int index=0;
                sales_rank(t.root,records,&index);
                sort_sales_records(records,index);
                print(index);
                break;        
                }
            default:
                printf("\t\t无效选项,请重新选择\n");
                break;
        }
    }
}

//管理员的登入函数
void adminInterface() 
{
    int tag=0;
    char password[20];
    char newpassword[20];
    char ch;
    //文件里存放管理员登入密码
    fp=fopen("password.txt","r");
    //第一次使用将打开失败
    if (fp == NULL)
    {     
        printf("\t\t文件打开失败!\n");
        return;
    }
    fscanf(fp, "%s", newpassword);
    fclose(fp);
    printf("\t\t请输入管理员密码:\n\t\t");
    scanf("%s", password);
    getchar();
    while(strcmp(password,newpassword) != 0) 
    {
        if(++tag==3)
        {
            printf("\t\t已经连续输错三次,安全系统启动\n");
            printf("\t\t需要修改密码则回复q\n\t\t");
            scanf("%c",&ch);
            if(ch=='q') 
            {
                printf("\t\t请输入您的新密码:\n\t\t");
                scanf("%s",newpassword);
                printf("\t\t密码修改成功\n");
                break;
            }
            return ;
        }
        printf("\t\t密码错误,请重新输入\n\t\t");
        scanf("%s", password);
        getchar();
    }
    printf("\t\t成功进入管理员选项\n");
    fp=fopen("password.txt","w");
    fprintf(fp, "%s", newpassword);
    fclose(fp);
    manageDishes();
}

//消费者的操作选项函数
int customerInterface() 
{
    printf("\t\t成功进入就餐者选项\n");
    while (1) 
    {
        int option;
        printf("\t\t======================\n");
        printf("\t\t请选择:\n");
        printf("\t\t[1] 查看菜单\n");
        printf("\t\t[2] 点餐\n");
        printf("\t\t[3] 结账离开\n");
        printf("\t\t[4] 热销菜品\n");
        printf("\t\t[5] 退出\n");
        printf("\t\t======================\n\t\t");
        scanf("%d", &option);
        switch (option) 
        {
            case 1:
                show_menu(&t);
                break;
            case 2:
                Ordering(&t);
                break;
            case 3:
                checkout();
                break;
            case 4:
                show_menu(&hottree);
                break;
            case 5:
                if(total_price!=0)
                {
                    printf("\t\t您还没有结账,请结账后再离开\n");
                    break;
                }
                printf("\t\t欢迎下次光临\n");
                return 0;
            default:
                printf("\t\t无效选项,请重新选择\n");
                break;
        }
    }
}

//按照先序读取文件到树里
void buildtree(struct dish **root)
{
    char name[20];
    float price;
    int quantity;
    int count;
    //判断文件是否读到末尾
    while(fscanf(fp, "%s%f%d%d", name, &price, &quantity,&count) == 4) 
    {
        struct dish *newDish = (struct dish *)malloc(sizeof(struct dish ));
        strcpy(newDish->name, name);
        newDish->price = price;
        newDish->quantity = quantity;
        newDish->count= count;
        newDish->left = newDish->right = NULL;
        if(*root==NULL) *root=newDish;
        else insert_node(*root,newDish);
    }
}

//按照先序存储菜单到文件里
void saveDishes(struct dish *root) 
{
    if(root) 
    {
        fprintf(fp, "%s %.2f %d %d\n", root->name, root->price, root->quantity, root->count);
        saveDishes(root->left);
        saveDishes(root->right);
    }
}

//读取菜单文件
void loadDishes(struct tree *t)
{
    //第一次使用将打开失败
    fp = fopen("dishes.txt", "r");
    if (fp == NULL) 
    {
        printf("\t\t文件打开失败!\n");
        return;
    }
    buildtree(&(t->root));
    fclose(fp);
}

//按照先序存储热销菜单到文件里
void saveHotDishes(struct dish *root)
{
    if(root) 
    {
        fprintf(fp, "%s %.2f %d\n", root->name, root->price, root->quantity);
        saveDishes(root->left);
        saveDishes(root->right);
    }
}
//读取热销菜单文件
void loadHotDishes(struct tree *hottree)
{
    //第一次使用将打开失败
    fp = fopen("hotdishes.txt", "r");
    if (fp == NULL) 
    {
        printf("\t\t文件打开失败!\n");
        return;
    }
    buildtree(&(hottree->root));
    fclose(fp);
}

// 主函数
int main() 
{
    
    system("color 9f");
    system("cls");
    init_tree(&t);
    init_tree(&hottree);
    loadDishes(&t);
    loadHotDishes(&hottree);
    int identity;//身份 1为管理者 2为就餐者
    while(1)
    {
            printf("\t\t******************登录系统*****************\n");
            printf("\t\t欢迎来到好运来餐厅!\n");
            printf("\t\t请输入登录身份:\n");
            printf("\t\t[1] 管理员\n");
           printf("\t\t[2] 就餐者\n");
           printf("\t\t[3] 退出\n");
           printf("\t\t*******************************************\n\t\t");
           scanf("%d", &identity);
         if(identity==3) 
         {
             printf("\n\t\t欢迎下次光临哦!!!!\n");
             break;
         }
         switch (identity) 
         {
             case 1:
                 adminInterface();break;
                
            case 2:
                customerInterface();break;
                
               default:
                printf("\t\t输入错误,请重新输入\n");
                
         }
    }
    //因为存储菜品需要遍历树,所以在主函数就将文件指针fp打开
    fp=fopen("dishes.txt","w");
    saveDishes(t.root);
    fclose(fp);
    fp=fopen("hotdishes.txt","w");
    saveHotDishes(hottree.root);
    fclose(fp);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值