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语言知识和编程技巧,也提高了自己的编程能力和解决问题的能力。在今后的学习和工作中,我会继续努力,不断提升自己的技能水平,为实现自己的梦想奋斗。

C语言餐厅点餐系统:功能实现与代码解析

原文地址: https://www.cveoy.top/t/topic/oA2G 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录