C语言餐厅点餐系统:功能实现与代码解析
C语言餐厅点餐系统:功能实现与代码解析
本次制作的餐厅点餐系统,是我在学习C语言编程过程中的一个练手项目。通过这个项目,我了解了很多关于C语言函数、结构体、文件操作、排序算法等方面的知识。同时,我也在实践中不断地掌握和提升自己的编程能力。
1. 结构体定义
首先,在本次项目中,我学习了如何定义和使用结构体。结构体是一种自定义的数据类型,它可以将不同类型的数据整合在一起,形成一个新的数据类型。在餐厅点餐系统中,我定义了菜品结构体和菜单结构体。
- 菜品结构体
// 菜品结构体
typedef struct {
char name[20]; // 菜品名称
int code; // 菜品编码
float price; // 菜品价格
} Dish;
菜品结构体包括菜品名称、菜品编码、菜品价格三个属性;
- 菜单结构体
// 菜单结构体
typedef struct {
Dish dishes[MAX_MENU_SIZE]; // 菜品数组
int count; // 菜品数量
} Menu;
菜单结构体包括菜品数组和菜品数量两个属性。通过结构体的使用,我可以更方便地对菜单进行管理和操作。
2. 文件操作
其次,在本次项目中,我学习了如何进行文件操作。文件操作是指对磁盘上的文件进行读、写等操作。在餐厅点餐系统中,我使用文件读写函数,将菜单保存到了本地文件中。这样,在下次运行程序时,就可以读取之前保存的菜单信息,方便用户进行点餐和管理。
- 保存菜单
// 保存菜单
void saveMenu(Menu* menu) {
FILE* file = fopen("menu.txt", "w");
if (file != NULL) {
for (int i = 0; i < menu->count - 1; i++) {
fprintf(file, "%s %d %.2f\n", menu->dishes[i].name, menu->dishes[i].code, menu->dishes[i].price);
}
fprintf(file, "%s %d %.2f", menu->dishes[i].name, menu->dishes[i].code, menu->dishes[i].price);
fclose(file);
printf("菜单保存成功!\n");
} else {
printf("菜单保存失败!\n");
}
}
- 加载菜单
// 加载菜单
void loadMenu(Menu* menu) {
FILE* file = fopen("menu.txt", "r");
if (file != NULL) {
while (!feof(file)) {
Dish dish;
fscanf(file, "%s %d %f", dish.name, &dish.code, &dish.price);
if (strlen(dish.name) > 0) {
menu->dishes[menu->count++]=dish;
}
}
fclose(file);
printf("菜单加载成功!\n");
} else {
printf("菜单加载失败!\n");
}
}
3. 排序算法
此外,在本次项目中,我也学习了不同的排序算法。在餐厅点餐系统中,我实现了按菜品价格和菜品编码两种方式对菜单进行排序。其中,按菜品价格排序使用了快速排序算法,按菜品编码排序使用了折半插入排序算法。通过学习排序算法,我对算法的理解和应用能力也得到了提升。
- 按菜品价格排序
// 针对数组中的区间[left, right]进行快速排序
void quickSort(Dish dishes[], int left, int right) {
if (left >= right) {
return;
}
int i = left; // 左指针
int j = right; // 右指针
Dish pivot = dishes[left]; // 基准值
while (i < j) {
// 从右往左找第一个小于基准值的元素
while (i < j && dishes[j].price >= pivot.price) {
j--;
}
if (i < j) {
dishes[i++] = dishes[j];
}
// 从左往右找第一个大于基准值的元素
while (i < j && dishes[i].price <= pivot.price) {
i++;
}
if (i < j) {
dishes[j--] = dishes[i];
}
}
// 将基准值放到中间位置
dishes[i] = pivot;
// 对基准值的左右两个子区间分别进行快速排序
quickSort(dishes, left, i - 1);
quickSort(dishes, i + 1, right);
}
// 按菜品价格排序
void sortByPrice(Menu* menu) {
quickSort(menu->dishes, 0, menu->count - 1);
printf("按价格排序完成!\n");
}
- 按菜品编码排序
// 折半插入排序
void binaryInsertionSort(Dish arr[], int n) {
for (int i = 1; i < n; i++) {
Dish temp = arr[i];
int left = 0; // 已经排序好的左边界
int right = i - 1; // 已经排序好的右边界
// 找到要插入位置的下标
while (left <= right) {
int mid = (left + right) / 2;
if (temp.code < arr[mid].code) {
right = mid - 1;
} else {
left = mid + 1;
}
}
// 把要插入的元素后移,空出插入位置
for (int j = i - 1; j >= left; j--) {
arr[j + 1] = arr[j];
}
// 把要插入的元素插入到对应位置
arr[left] = temp;
}
}
// 按菜品编码排序
void sortByCode(Menu* menu) {
binaryInsertionSort(menu->dishes, menu->count);
printf("按编码排序完成!\n");
}
4. 函数实现
最后,在本次项目中,我也加深了对C语言函数的理解和应用。函数是C语言中的一种重要的模块化编程方式,它可以将程序分成多个功能模块,提高程序的可读性和可维护性。在餐厅点餐系统中,我定义了多个函数来实现不同的功能,如添加菜品、删除菜品、排序等。通过函数的使用,代码的复用性和可扩展性也得到了提升。
- 添加菜品
// 添加菜品
void addDish(Menu* menu) {
Dish dish;
printf(" ________________________________\n");
printf("| |\n");
printf("|-------------菜单---------------|\n");
printf("|-------1.鱼子酱-价格:300-------|\n");
printf("|-------2.冰淇淋-价格:40 -------|\n");
printf("|-------3.葱烧海参-价格:200-----|\n");
printf("|-------4.菲力牛排-价格:350-----|\n");
printf("|-------5.三文鱼寿司-价格:300---|\n");
printf("|________________________________|\n");
/* printf("请输入菜品名称:");
scanf("%s", &dish.name);*/
printf("请输入菜品编码:");
scanf("%d", &dish.code);
/* printf("请输入菜品价格:");
scanf("%f", &dish.price);*/
if (menu->count >= MAX_MENU_SIZE) {
printf("菜单已满,无法添加菜品!\n");
} else {
switch(dish.code)
{case 1:strcpy(dish.name,"鱼子酱");dish.price=300;break;
case 2 :strcpy(dish.name,"冰淇淋");dish.price=40;break;
case 3:strcpy(dish.name,"葱烧海参");dish.price=200;break;
case 4:strcpy(dish.name,"菲力牛排");dish.price=350;break;
case 5:strcpy(dish.name,"三文鱼寿司");dish.price=300;break;
}
menu->dishes[menu->count++] = dish;
printf("菜品添加成功!\n");
}
}
- 删除菜品
// 删除菜品
void deleteDish(Menu* menu) {
int code, index = -1;
printf("请输入要删除的菜品编码:");
scanf("%d", &code);
for (int i = 0; i < menu->count; i++) {
if (menu->dishes[i].code == code) {
index = i;
break;
}
}
if (index == -1) {
printf("没有找到要删除的菜品!\n");
} else {
for (int i = index; i < menu->count - 1; i++) {
menu->dishes[i] = menu->dishes[i + 1];
}
menu->count--;
printf("菜品删除成功!\n");
}
}
- 遍历菜单
// 遍历菜单
void traverseMenu(Menu* menu) {
printf("菜单:\n");
if(menu->count!=0)
for (int i = 0; i < menu->count; i++) {
printf("%s\t%d\t%.2f元\n", menu->dishes[i].name, menu->dishes[i].code, menu->dishes[i].price);
}
else printf("当前未点餐\n");
}
- 结账
// 结账函数
void checkout(Menu* menu) {
float sum = 0;
for (int i = 0; i < menu->count; i++) {
sum += menu->dishes[i].price;
}
printf("总消费金额为:%.2f 元\n", sum);
// 清空菜单缓存,重新生成空的菜单结构体
menu->count = 0;
//menu->dishes = NULL;
// 清空文件
FILE* file = fopen("menu.txt", "w");
if (file != NULL) {
fclose(file);
printf("菜单文件清空成功!\n");
} else {
printf("菜单文件清空失败!\n");
}
}
5. 管理员和用户身份验证
该系统还实现了管理员和用户两种身份权限,管理员可以查看用户已点菜品、为用户结账、删除菜品,而用户则可以点餐、删除菜品、排序、输出已点餐品、保存菜单等操作。
// 主函数
int main() {
system("color B");
Menu menu;
menu.count = 0;
int choice;
loadMenu(&menu);
int tag;
while(1)
{
lable:printf("*----------------------------------------------*\n");
printf("|***** 请选择你的身份(1.管理员 2.用户) ********|\n");
printf("*----------------------------------------------*\n");
scanf("%d","&tag);
//system ("cls");
if(tag==1)
{
int sign=1,i;
char ch[20],a;
printf("请输入密码:");
while(sign)
{
i=0;
while(1)
{
a=getch();
if(a=='\r') break;
ch[i]=a;
printf("*");
i++;
}
ch[i]=’\0';
if(strcmp("123123",ch)==0) {printf("\n密码正确\n");sign=0;}
else printf("\n密码错误,请重新输入:\n");
}
//system ("cls");
printf("----------------------------------------\n");
printf("==================管理员================\n");
printf("+ 1.查看用户已点菜品 +");
printf("+ 2.为用户结账 +");
printf("+ 3.返回上一级 +");
printf("+ 4.删除菜品 +");
printf("----------------------------------------\n");
while(1)
{
printf("请输入:\n");
int biaoji;
scanf("%d","&biaoji);
switch(biaoji)
{
case 1:traverseMenu(&menu);break;
//结账函数
case 2:
checkout(&menu);break;
case 3:system ("cls");goto lable;break;
case 4:deleteDish(&menu);break;
default:printf("您的输入有误,请重新输入!\n");break;
}
}
break;
}
else if(tag==2)
{
while (1) {
printf("\n");
printf("----------------------------------------\n");
printf("=============餐厅用户点餐系统===========");
printf("+ 1.点餐 +");
printf("+ 2.删除菜品 +");
printf("+ 3.将已点餐品按价格排序 +");
printf("+ 4.将已点餐品按编码排序 +");
printf("+ 5.输出已点餐品 +");
printf("+ 6.保存菜单 +");
printf("+ 7.返回上一级 +");
printf("+ 8.按照菜名查看是否已点 +");
printf("+ 9.按照编号查看是否已点 +");
printf("+ 0.退出系统 +");
printf("----------------------------------------\n");
printf("请输入您的选择(0-9):");
scanf("%d", &choice);
switch (choice) {
case 0:
printf("欢迎再次光临!\n");
return 0;
case 1: system ("cls");
addDish(&menu);
break;
case 2:system ("cls");
deleteDish(&menu);
break;
case 3:system ("cls");
sortByPrice(&menu);
break;
case 4:system ("cls");
sortByCode(&menu);
break;
case 5:system ("cls");
traverseMenu(&menu);
break;
case 6:system ("cls");
saveMenu(&menu);
break;
case 7:system ("cls");
goto lable;break;
case 8:system ("cls");
search_shunxu(&menu);break;
case 9:system ("cls"); int e;printf("请输入编码:");scanf("%d","&e); sortByCode(&menu); Search_Bin(&menu,e);break;
break;
default:
printf("您的输入有误,请重新输入!\n");
break;
}
}
break;
}
else
printf("输入错误请重新输入:\n");
}
return 0;
}
6. 收获与体会
总之,通过这个餐厅点餐系统的制作,我不仅掌握了更多的C语言知识和编程技巧,也提高了自己的编程能力和解决问题的能力。在今后的学习和工作中,我会继续努力,不断提升自己的技能水平,为实现自己的梦想奋斗。
原文地址: https://www.cveoy.top/t/topic/oA2G 著作权归作者所有。请勿转载和采集!