要求必须使用C语言链表,要求使用文件的读取与输入,文件要求使用相对路径。
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
#include
#define MAX_USERNAME_LENGTH 20
#define MAX_PASSWORD_LENGTH 20
typedef struct
{
char username[MAX_USERNAME_LENGTH];
char password[MAX_PASSWORD_LENGTH];
} User;
User admin = { "admin", "123456" };
typedef struct
{
int dishId;
char dishName[100];
float price;
int rating;
} Dish;
typedef struct dishNode
{
Dish dish;
struct dishNode* next;
} DishNode;
typedef struct
{
int tableNumber;
DishNode* dishList;
} Order;
typedef struct orderNode
{
Order order;
struct orderNode* next;
} OrderNode;
OrderNode* orderList = NULL;
DishNode* menuList = NULL;
// 函数声明
void printMenu();
void addDish();
void editDish();
void deleteDish();
void viewMenu();
void placeOrder();
void editOrder();
void deleteOrder();
void viewOrderHistory();
void calculateTotalBill();
void rateDish();
void addNormalUser() {
User newUser;
printf("\n请输入新用户的用户名:");
scanf("%s", newUser.username);
printf("请输入新用户的密码:");
scanf("%s", newUser.password);
FILE* file = fopen("user_data.dat", "ab");
if (file == NULL) {
printf("无法打开文件。\n");
return;
}
fwrite(&newUser, sizeof(User), 1, file);
fclose(file);
printf("新用户已添加。\n");
}
void resetNormalUserPassword() {
char username[MAX_USERNAME_LENGTH];
printf("\n请输入要重置密码的普通用户用户名:");
scanf("%s", username);
FILE* file = fopen("user_data.dat", "rb+");
if (file == NULL) {
printf("无法打开文件。\n");
return;
}
User user;
while (fread(&user, sizeof(User), 1, file)) {
if (strcmp(user.username, username) == 0) {
fseek(file, sizeof(User), SEEK_CUR);
printf("请输入新密码:");
scanf("%s", user.password);
fwrite(&user, sizeof(User), 1, file);
fclose(file);
printf("密码已重置。\n");
return;
}
}
fclose(file);
printf("未找到该用户。\n");
}
void viewAllOrders()
{
printf("\n====== 所有座台点餐订单 ======\n");
OrderNode* current = orderList;
while (current != NULL) {
// 打印订单信息
printf("座台编号:%d\n", current -> order.tableNumber);
// 遍历订单的菜品列表并打印
DishNode* dishNode = current -> order.dishList;
while (dishNode != NULL) {
printf("菜品编号:%d\n", dishNode->dish.dishId);
printf("菜品名称:%s\n", dishNode->dish.dishName);
printf("价格:%f\n", dishNode->dish.price);
printf("评分:%d\n", dishNode->dish.rating);
dishNode = dishNode->next;
}
current = current->next;
}
}
void calculateTotalRevenue() {
printf("\n====== 总消费统计 ======\n");
float totalRevenue = 0.0;
OrderNode* current = orderList;
while (current != NULL) {
// 打印订单信息
printf("座台编号:%d\n", current->order.tableNumber);
// 遍历订单的菜品列表并打印
DishNode* dishNode = current->order.dishList;
while (dishNode != NULL) {
totalRevenue += dishNode->dish.price;
dishNode = dishNode->next;
}
current = current->next;
}
printf("总消费金额:%.2f\n", totalRevenue);
}
void viewAllHistory() {
printf("\n====== 所有消费历史 ======\n");
OrderNode* current = orderList;
while (current != NULL) {
// 打印订单信息
printf("座台编号:%d\n", current->order.tableNumber);
// 遍历订单的菜品列表并打印
DishNode* dishNode = current->order.dishList;
while (dishNode != NULL) {
printf("菜品编号:%d\n", dishNode->dish.dishId);
printf("菜品名称:%s\n", dishNode->dish.dishName);
printf("价格:%f\n", dishNode->dish.price);
printf("评分:%d\n", dishNode->dish.rating);
dishNode = dishNode->next;
}
current = current->next;
}
}
void addDish()
{
Dish newDish;
printf("\n请输入新菜品的编号:");
scanf("%d", &newDish.dishId);
printf("请输入新菜品的名称:");
scanf("%s", newDish.dishName);
printf("请输入新菜品的单价:");
scanf("%f", &newDish.price);
printf("请输入新菜品的评分:");
scanf("%d", &newDish.rating);
DishNode* newNode = (DishNode*)malloc(sizeof(DishNode));
newNode->dish = newDish;
newNode->next = NULL;
// 将新菜品添加到菜单链表末尾
if (menuList == NULL)
{
menuList = newNode;
}
else {
DishNode* current = menuList;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
printf("菜品已添加。\n");
}
void menuManagement()
{
int choice;
do {
printf("\n====== 菜单管理 ======\n");
printf("1. 添加菜品\n");
printf("2. 返回\n");
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
addDish();
break;
case 2:
break;
default:
printf("无效的选项,请重新选择。\n");
break;
}
} while (choice != 2);
}
char* HidePassword()//隐藏密码
{
char password[18];//密码
char* p;//指向密码的指针
int i = 0;//记录密码位数
char t;//输入密码
for (;;) //此处为输入密码不回显操作
{
t = _getch(); //输入k
if (t == '\r') //如果输入k为回车,则跳出循环
{
break;
}
else if (t == '\b') //如果输入k为删除键
{
if (i > 0) //如若密码还没完全删除
{
printf("\b");
printf(" ");
printf("\b");
i--;
}
}
else //如果输入的k既不是删除键,也不是回车键
{
password[i] = t; //把k的值赋给_password[i];
printf("*"); //输出*号,保护用户隐私
i++; //密码位数加1
}
}
password[i] = '\0';//在数组末端加一个结束符
p = password;//让p指向该数组
return p; //返回一个指向密码的指针
}
int login()
{
char username[MAX_USERNAME_LENGTH];
printf("\n请输入用户名:");
scanf("%s", username);
printf("请输入密码:");
char* p;
char _password[18];
p = HidePassword();
strcpy(_password, p);
if (strcmp(username, admin.username) == 0 && strcmp(_password, admin.password) == 0)
{
printf("\n管理员登录成功。\n");
return 1; // 返回1表示管理员登录成功
}
else
{
printf("\n登录失败");
return login();
}
}
int userlogin()
{
char username[MAX_USERNAME_LENGTH];
printf("\n请输入用户名:");
scanf("%s", username);
printf("请输入密码:");
char* p;
char _password[18];
p = HidePassword();
strcpy(_password, p);
FILE* file = fopen("user_data.dat", "rb");
if (file == NULL)
{
printf("无法打开文件。\n");
return 0;
}
User user;
while (fread(&user, sizeof(User), 1, file)) {
if (strcmp(username, user.username) == 0 && strcmp(_password, user.password) == 0)
{
printf("\n普通用户登录成功。\n");
return 1; // 返回1表示普通用户登录成功
}
}
fclose(file);
printf("\n登录失败");
return userlogin();
}
int main()
{
int isAdmin = 0;
int isLoggedIn = 0;
int choice;
printf("===== 欢迎使用酒店点菜管理系统 =====\n");
while (!isLoggedIn)
{
printf("\n====== 登录 ======\n");
printf("1. 管理员登录\n");
printf("2. 普通用户登录\n");
printf("3. 退出\n");
printf("请选择登录类型:");
scanf("%d", &choice);
switch (choice)
{
case 1:
isAdmin = login();
isLoggedIn = 1;
break;
case 2:
isLoggedIn = userlogin();
break;
case 3:
printf("谢谢使用,再见!\n");
return 0;
default:
printf("无效的选项,请重新选择。\n");
break;
}
}
while (isAdmin)
{
printf("\n====== 管理员功能菜单 ======\n");
printf("1. 添加普通用户\n");
printf("2. 重置普通用户初始密码\n");
printf("3. 权限管理\n");
printf("4. 查看所有座台点餐订单\n");
printf("5. 结账管理\n");
printf("6. 查看所有消费历史\n");
printf("7. 菜单管理\n");
printf("8. 退出\n");
printf("请选择操作:");
scanf("%d", &choice);
switch (choice) {
case 1:
addNormalUser();
break;
case 2:
resetNormalUserPassword();
break;
case 3:
addNormalUser();
break;
case 4:
viewAllOrders();
break;
case 5:
calculateTotalRevenue();
break;
case 6:
viewAllHistory();
break;
case 7:
menuManagement();
break;
case 8:
printf("谢谢使用,再见!\n");
return main();
default:
printf("无效的选项,请重新选择。\n");
break;
}
}
while (1)
{
printf("\n====== 酒店点菜管理系统 ======\n");
printf("1. 点餐功能\n");
printf("2. 修改菜单\n");
printf("3. 删除菜单\n");
printf("4. 查看菜单\n");
printf("5. 生成订单\n");
printf("6. 修改订单\n");
printf("7. 删除订单\n");
printf("8. 查看订单历史\n");
printf("9. 结账管理\n");
printf("10. 菜谱评分\n");
printf("0. 退出系统\n");
printf("请输入您的选择:");
scanf("%d", &choice);
switch (choice) {
case 1:
placeOrder();
break;
case 2:
addDish();
break;
case 3:
deleteDish();
break;
case 4:
viewMenu();
break;
case 5:
placeOrder();
break;
case 6:
editOrder();
break;
case 7:
deleteOrder();
break;
case 8:
viewOrderHistory();
break;
case 9:
calculateTotalBill();
break;
case 10:
rateDish();
break;
case 0:
printf("感谢使用酒店点菜管理系统!\n");
return main();
default:
printf("无效的选择,请重新输入。\n");
break;
}
}while (choice != 0);
return 0;
}
DishNode* current = menuList;
void printMenu() {
printf("\n====== 酒店菜单 ======\n");
printf("菜品编号 菜名 价格 评分\n");
// 遍历菜单链表并打印菜品信息
DishNode* current = menuList;
while (current != NULL) {
printf("%d %s %.2f %d\n", current->dish.dishId, current->dish.dishName, current->dish.price, current->dish.rating);
current = current->next;
}
}
void editDish() {
int dishId;
printf("\n请输入要修改的菜品编号:");
scanf("%d", &dishId);
DishNode* current = menuList;
while (current != NULL) {
if (current->dish.dishId == dishId) {
printf("请输入新的菜名:");
scanf("%s", current->dish.dishName);
printf("请输入新的价格:");
scanf("%f", ¤t->dish.price);
printf("请输入新的评分:");
scanf("%d", ¤t->dish.rating);
printf("菜品已修改。\n");
return;
}
current = current->next;
}
printf("未找到指定菜品。\n");
}
void deleteDish() {
int dishId;
printf("\n请输入要删除的菜品编号:");
scanf("%d", &dishId);
if (menuList == NULL)
{
printf("菜单为空。\n");
return;
}
if (menuList->dish.dishId == dishId)
{
DishNode* temp = menuList;
menuList = menuList->next;
free(temp);
printf("菜品已删除。\n");
return;
}
DishNode* current = menuList;
while (current->next != NULL) {
if (current->next->dish.dishId == dishId) {
DishNode* temp = current->next;
current->next = current->next->next;
free(temp);
printf("菜品已删除。\n");
return;
}
current = current->next;
}
printf("未找到指定菜品。\n");
}
void viewMenu() {
printMenu();
}
void placeOrder() { //生成订单
Order newOrder = {};
printf("\n请输入座台号:");
scanf("%d", &newOrder.tableNumber);
int dishId;
char choice;
do {
printf("请输入要点菜的菜品编号:");
scanf("%d", &dishId);
// 根据菜品编号查找对应的菜品
DishNode* current = menuList;
while (current != NULL) {
if (current->dish.dishId == dishId) {
DishNode* newNode = (DishNode*)malloc(sizeof(DishNode));
newNode->dish = current->dish;
newNode->next = NULL;
// 将菜品添加到订单的菜品链表末尾
if (newOrder.dishList == NULL) {
newOrder.dishList = newNode;
}
else {
DishNode* dishCurrent = newOrder.dishList;
while (dishCurrent->next != NULL) {
dishCurrent = dishCurrent->next;
}
dishCurrent->next = newNode;
}
break;
}
current = current->next;
}
printf("是否继续点菜?(y/n): ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');
OrderNode* newNode = (OrderNode*)malloc(sizeof(OrderNode));
newNode->order = newOrder;
newNode->next = NULL;
// 将新订单添加到订单链表末尾
if (orderList == NULL) {
orderList = newNode;
}
else {
OrderNode* current = orderList;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
printf("订单已生成。\n");
}
void editOrder() {
int tableNumber;
printf("\n请输入要修改的订单座台号:");
scanf("%d", &tableNumber);
OrderNode* current = orderList;
while (current != NULL) {
if (current->order.tableNumber == tableNumber) {
int dishId;
char choice;
printf("请输入要修改的菜品编号:");
scanf("%d", &dishId);
// 根据菜品编号查找对应的菜品
DishNode* dishCurrent = current->order.dishList;
while (dishCurrent != NULL) {
if (dishCurrent->dish.dishId == dishId) {
printf("请输入新的菜名:");
scanf("%s", &dishCurrent->dish.dishName);
printf("请输入新的价格:");
scanf("%f", &(dishCurrent->dish.price));
printf("请输入新的评分:");
scanf("%d", &(dishCurrent->dish.rating));
printf("菜品已修改。\n");
return;
}
dishCurrent = dishCurrent->next;
}
printf("未找到指定菜品。\n");
return;
}
current = current->next;
}
printf("未找到指定订单。\n");
}
void deleteOrder() {
int tableNumber;
printf("\n请输入要删除的订单座台号:");
scanf("%d", &tableNumber);
if (orderList == NULL) {
printf("订单列表为空。\n");
return;
}
if (orderList->order.tableNumber == tableNumber) {
OrderNode* temp = orderList;
orderList = orderList->next;
// 释放订单菜品链表的内存
DishNode* current = temp->order.dishList;
while (current != NULL) {
DishNode* dishTemp = current;
current = current->next;
free(dishTemp);
}
free(temp);
printf("订单已删除。\n");
return;
}
OrderNode* current = orderList;
while (current->next != NULL) {
if (current->next->order.tableNumber == tableNumber) {
OrderNode* temp = current->next;
current->next = current->next->next;
// 释放订单菜品链表的内存
DishNode* dishCurrent = temp->order.dishList;
while (dishCurrent != NULL) {
DishNode* dishTemp = dishCurrent;
dishCurrent = dishCurrent->next;
free(dishTemp);
}
free(temp);
printf("订单已删除。\n");
return;
}
current = current->next;
}
printf("未找到指定订单。\n");
}
void viewOrderHistory() {
printf("\n====== 订单历史记录 ======\n");
printf("座台号 菜品编号 菜名 价格 评分\n");
// 遍历订单链表并打印订单信息
OrderNode* current = orderList;
while (current != NULL) {
printf("%d ", current->order.tableNumber);
DishNode* dishCurrent = current->order.dishList;
while (dishCurrent != NULL) {
printf("%d %s %.2f %d\n", dishCurrent->dish.dishId, dishCurrent->dish.dishName, dishCurrent->dish.price, dishCurrent->dish.rating);
dishCurrent = dishCurrent->next;
}
current = current->next;
}
}
void calculateTotalBill()
{
int tableNumber;
printf("\n请输入要结账的订单座台号:");
scanf("%d", &tableNumber);
OrderNode* current = orderList;
while (current != NULL) {
if (current->order.tableNumber == tableNumber) {
float totalBill = 0.0;
DishNode* dishCurrent = current->order.dishList;
while (dishCurrent != NULL) {
totalBill += dishCurrent->dish.price;
dishCurrent = dishCurrent->next;
}
printf("座台号:%d\n", current->order.tableNumber);
printf("总消费:%0.2f\n", totalBill);
return;
}
current = current->next;
}
printf("未找到指定订单。\n");
}
void rateDish() {
int dishId;
printf("\n请输入要评分的菜品编号:");
scanf("%d", &dishId);
current = menuList; //DishNode* current = menuList;
while (current != NULL) {
if (current->dish.dishId == dishId) {
int rating;
printf("请输入菜品评分(1-5):");
scanf("%d", &rating);
if (rating < 1 || rating > 5) {
printf("无效的评分。\n");
return;
}
current->dish.rating = rating;
printf("菜品评分已更新。\n");
return;
}
current = current->next;
}
printf("未找到指定菜品。\n");
}