lovers -A

file.h文件: #ifndef FILE_H #define FILE_H #include "data.h" void save_data(); void load_data(); void save_lovers(); void load_lovers(); #endif recipe.c文件: #ifndef RECIPE_H #define RECIPE_H #include "data.h" // 菜谱管理 void add_recipe(); void delete_recipe(); void modify_recipe(); void search_recipes(); void random_recommendation(); // 辅助函数 void print_recipe(Recipe* recipe); Recipe* find_recipe_by_id(int id); Recipe* find_recipe_by_name(const char* name); void get_multi_select_options(const char* prompt, int* flags, const char* options[], int count); void get_meal_type(MealType* meal_type); void get_cuisine(Cuisine* cuisine); void get_lovers(char lovers[][MAX_NAME_LEN], int* count); #endif data.h文件: #ifndef DATA_H #define DATA_H #include <stdbool.h> // 常量定义 #define MAX_NAME_LEN 50 #define MAX_INGREDIENTS 20 #define MAX_STEPS 20 #define MAX_LOVERS 10 #define MAX_RECIPES 100 // 枚举定义 typedef enum { BREAKFAST, MAIN_COURSE, DESSERT, SNACK, DRINK } MealType; typedef enum { SOUR = 1, SWEET = 2, BITTER = 4, SPICY = 8, SALTY = 16, COLD = 32, HOT = 64 } Taste; typedef enum { SOUP = 1, DRY = 2, WET = 4, CRISPY = 8, SOFT = 16, HARD = 32 } State; typedef enum { LU, CHUAN, YUE, SU, MIN, ZHE, XIANG, HUI, DONGBEI, HOME, WESTERN } Cuisine; // 菜谱结构体 typedef struct Recipe { int id;//自动生成的id char name[MAX_NAME_LEN];//菜名 MealType meal_type;//餐型 int taste_flags;//口味 int state_flags;//状态 Cuisine cuisine;//菜系 //食材 char ingredients[MAX_INGREDIENTS][MAX_NAME_LEN]; int ingredient_count; //步骤 char steps[MAX_STEPS][MAX_NAME_LEN * 2]; int step_count; int cooking_time;//时间 //喜好者 char lovers[MAX_LOVERS][MAX_NAME_LEN]; int lover_count; struct Recipe* next; } Recipe; // 全局数据 extern Recipe* recipe_list; extern int recipe_count; extern char lovers_list[MAX_LOVERS][MAX_NAME_LEN]; extern int lover_count; #endif file.c文件: #include <stdio.h> #include <stdlib.h> #include <string.h> #include "data.h" void save_data() { FILE* file = fopen("recipes.dat", "wb"); if (!file) { perror("无法保存数据"); return; } Recipe* current = recipe_list; while (current) { fwrite(current, sizeof(Recipe), 1, file); current = current->next; } fclose(file); printf("数据保存成功!\n"); } void load_data() { FILE* file = fopen("recipes.dat", "rb"); if (!file) return; Recipe* last = NULL; while (!feof(file)) { Recipe* new_recipe = (Recipe*)malloc(sizeof(Recipe)); if (fread(new_recipe, sizeof(Recipe), 1, file) != 1) { free(new_recipe); break; } new_recipe->next = NULL; if (!recipe_list) { recipe_list = new_recipe; } else { last->next = new_recipe; } last = new_recipe; recipe_count++; } fclose(file); } void save_lovers() { FILE* file = fopen("lovers.dat", "w"); if (!file) { perror("无法保存喜好者数据"); return; } for (int i = 0; i < lover_count; i++) { fprintf(file, "%s\n", lovers_list[i]); } fclose(file); } void load_lovers() { FILE* file = fopen("lovers.dat", "r"); if (!file) return; char line[MAX_NAME_LEN]; lover_count = 0; while (fgets(line, sizeof(line), file) && lover_count < MAX_LOVERS) { line[strcspn(line, "\n")] = '\0'; strcpy(lovers_list[lover_count++], line); } fclose(file); } recipe.c文件: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "data.h" #include "recipe.h" // 辅助函数:获取多选选项 void get_multi_select_options(const char* prompt, int* flags, const char* options[], int count) { printf("%s (输入空行结束):\n", prompt); for (int i = 0; i < count; i++) { printf("%d. %s\n", i+1, options[i]); } *flags = 0; char input[10]; while (1) { fgets(input, sizeof(input), stdin); if (input[0] == '\n') break; int choice = atoi(input); if (choice > 0 && choice <= count) { *flags |= (1 << (choice-1)); } } } // 辅助函数:获取餐型 void get_meal_type(MealType* meal_type) { const char* meals[] = {"早餐", "正餐", "甜品", "零食", "饮品"}; printf("选择餐型:\n"); for (int i = 0; i < 5; i++) { printf("%d. %s\n", i+1, meals[i]); } printf("请选择: "); int choice; scanf("%d", &choice); getchar(); *meal_type = (MealType)(choice-1); } // 辅助函数:获取菜系 void get_cuisine(Cuisine* cuisine) { const char* cuisines[] = {"鲁菜", "川菜", "粤菜", "苏菜", "闽菜", "浙菜", "湘菜", "徽菜", "东北菜", "家常菜", "西餐"}; printf("选择菜系:\n"); for (int i = 0; i < 11; i++) { printf("%d. %s\n", i+1, cuisines[i]); } printf("请选择: "); int choice; scanf("%d", &choice); getchar(); *cuisine = (Cuisine)(choice-1); } // 辅助函数:获取喜好者 void get_lovers(char lovers[][MAX_NAME_LEN], int* count) { printf("当前喜好者:\n"); for (int i = 0; i < lover_count; i++) { printf("%d. %s\n", i+1, lovers_list[i]); } printf("选择喜好者 (输入空行结束):\n"); *count = 0; char input[10]; while (*count < MAX_LOVERS) { fgets(input, sizeof(input), stdin); if (input[0] == '\n') break; int choice = atoi(input); if (choice > 0 && choice <= lover_count) { strcpy(lovers[*count], lovers_list[choice-1]); (*count)++; } } } // 打印菜谱详情 void print_recipe(Recipe* recipe) { if (!recipe) return; const char* meals[] = {"早餐", "正餐", "甜品", "零食", "饮品"}; const char* cuisines[] = {"鲁菜", "川菜", "粤菜", "苏菜", "闽菜", "浙菜", "湘菜", "徽菜", "东北菜", "家常菜", "西餐"}; printf("\n菜谱ID: %d\n", recipe->id); printf("菜名: %s\n", recipe->name); printf("餐型: %s\n", meals[recipe->meal_type]); printf("口味: "); if (recipe->taste_flags & SOUR) printf("酸 "); if (recipe->taste_flags & SWEET) printf("甜 "); if (recipe->taste_flags & BITTER) printf("苦 "); if (recipe->taste_flags & SPICY) printf("辣 "); if (recipe->taste_flags & SALTY) printf("咸 "); if (recipe->taste_flags & COLD) printf("凉 "); if (recipe->taste_flags & HOT) printf("热 "); printf("\n"); printf("状态: "); if (recipe->state_flags & SOUP) printf("汤 "); if (recipe->state_flags & DRY) printf("干 "); if (recipe->state_flags & WET) printf("湿 "); if (recipe->state_flags & CRISPY) printf("脆 "); if (recipe->state_flags & SOFT) printf("软 "); if (recipe->state_flags & HARD) printf("硬 "); printf("\n"); printf("菜系: %s\n", cuisines[recipe->cuisine]); printf("食材:\n"); for (int i = 0; i < recipe->ingredient_count; i++) { printf(" - %s\n", recipe->ingredients[i]); } printf("步骤:\n"); for (int i = 0; i < recipe->step_count; i++) { printf("%d. %s\n", i+1, recipe->steps[i]); } printf("烹饪时间: %d分钟\n", recipe->cooking_time); printf("喜好者: "); for (int i = 0; i < recipe->lover_count; i++) { printf("%s ", recipe->lovers[i]); } printf("\n"); } // 通过ID查找菜谱 Recipe* find_recipe_by_id(int id) { Recipe* current = recipe_list; while (current) { if (current->id == id) return current; current = current->next; } return NULL; } // 通过名称查找菜谱 Recipe* find_recipe_by_name(const char* name) { Recipe* current = recipe_list; while (current) { if (strcmp(current->name, name) == 0) return current; current = current->next; } return NULL; } // 添加菜谱 void add_recipe() { Recipe* new_recipe = (Recipe*)malloc(sizeof(Recipe)); new_recipe->id = recipe_count + 1; printf("输入菜名: "); fgets(new_recipe->name, MAX_NAME_LEN, stdin); new_recipe->name[strcspn(new_recipe->name, "\n")] = '\0'; get_meal_type(&new_recipe->meal_type); // 获取口味 const char* tastes[] = {"酸", "甜", "苦", "辣", "咸", "凉", "热"}; get_multi_select_options("选择口味", &new_recipe->taste_flags, tastes, 7); // 获取状态 const char* states[] = {"汤", "干", "湿", "脆", "软", "硬"}; get_multi_select_options("选择状态", &new_recipe->state_flags, states, 6); get_cuisine(&new_recipe->cuisine); // 获取食材 printf("输入食材 (每行一种,空行结束):\n"); new_recipe->ingredient_count = 0; char ingredient[MAX_NAME_LEN]; while (new_recipe->ingredient_count < MAX_INGREDIENTS) { fgets(ingredient, MAX_NAME_LEN, stdin); if (ingredient[0] == '\n') break; ingredient[strcspn(ingredient, "\n")] = '\0'; strcpy(new_recipe->ingredients[new_recipe->ingredient_count], ingredient); new_recipe->ingredient_count++; } // 获取步骤 printf("输入步骤 (每行一步,空行结束):\n"); new_recipe->step_count = 0; char step[MAX_NAME_LEN * 2]; while (new_recipe->step_count < MAX_STEPS) { fgets(step, MAX_NAME_LEN * 2, stdin); if (step[0] == '\n') break; step[strcspn(step, "\n")] = '\0'; strcpy(new_recipe->steps[new_recipe->step_count], step); new_recipe->step_count++; } printf("输入烹饪时间(分钟): "); scanf("%d", &new_recipe->cooking_time); getchar(); get_lovers(new_recipe->lovers, &new_recipe->lover_count); // 添加到链表 new_recipe->next = recipe_list; recipe_list = new_recipe; recipe_count++; printf("\n添加成功! 菜谱详情:\n"); print_recipe(new_recipe); } // 删除菜谱 void delete_recipe() { printf("1. 按ID查找\n2. 按名称查找\n选择查找方式: "); int choice; scanf("%d", &choice); getchar(); Recipe* target = NULL; if (choice == 1) { printf("输入菜谱ID: "); int id; scanf("%d", &id); getchar(); target = find_recipe_by_id(id); } else if (choice == 2) { printf("输入菜名: "); char name[MAX_NAME_LEN]; fgets(name, MAX_NAME_LEN, stdin); name[strcspn(name, "\n")] = '\0'; target = find_recipe_by_name(name); } if (!target) { printf("未找到菜谱!\n"); return; } print_recipe(target); printf("确认删除? (y/n): "); char confirm; scanf("%c", &confirm); getchar(); if (confirm == 'y' || confirm == 'Y') { // 从链表中删除 if (target == recipe_list) { recipe_list = recipe_list->next; } else { Recipe* prev = recipe_list; while (prev->next != target) prev = prev->next; prev->next = target->next; } free(target); recipe_count--; printf("删除成功!\n"); } else { printf("取消删除\n"); } } // 修改菜谱 void modify_recipe() { printf("1. 按ID查找\n2. 按名称查找\n选择查找方式: "); int choice; scanf("%d", &choice); getchar(); Recipe* target = NULL; if (choice == 1) { printf("输入菜谱ID: "); int id; scanf("%d", &id); getchar(); target = find_recipe_by_id(id); } else if (choice == 2) { printf("输入菜名: "); char name[MAX_NAME_LEN]; fgets(name, MAX_NAME_LEN, stdin); name[strcspn(name, "\n")] = '\0'; target = find_recipe_by_name(name); } if (!target) { printf("未找到菜谱!\n"); return; } print_recipe(target); printf("选择要修改的项:\n"); printf("1. 菜名\n2. 餐型\n3. 口味\n4. 状态\n5. 菜系\n"); printf("6. 食材\n7. 步骤\n8. 时间\n9. 喜好者\n"); printf("选择: "); int mod_choice; scanf("%d", &mod_choice); getchar(); switch(mod_choice) { case 1: printf("输入新菜名: "); fgets(target->name, MAX_NAME_LEN, stdin); target->name[strcspn(target->name, "\n")] = '\0'; break; case 2: get_meal_type(&target->meal_type); break; case 3: { const char* tastes[] = {"酸", "甜", "苦", "辣", "咸", "凉", "热"}; get_multi_select_options("选择新口味", &target->taste_flags, tastes, 7); break; } case 4: { const char* states[] = {"汤", "干", "湿", "脆", "软", "硬"}; get_multi_select_options("选择新状态", &target->state_flags, states, 6); break; } case 5: get_cuisine(&target->cuisine); break; case 6: printf("输入新食材 (每行一种,空行结束):\n"); target->ingredient_count = 0; char ingredient[MAX_NAME_LEN]; while (target->ingredient_count < MAX_INGREDIENTS) { fgets(ingredient, MAX_NAME_LEN, stdin); if (ingredient[0] == '\n') break; ingredient[strcspn(ingredient, "\n")] = '\0'; strcpy(target->ingredients[target->ingredient_count], ingredient); target->ingredient_count++; } break; case 7: printf("输入新步骤 (每行一步,空行结束):\n"); target->step_count = 0; char step[MAX_NAME_LEN * 2]; while (target->step_count < MAX_STEPS) { fgets(step, MAX_NAME_LEN * 2, stdin); if (step[0] == '\n') break; step[strcspn(step, "\n")] = '\0'; strcpy(target->steps[target->step_count], step); target->step_count++; } break; case 8: printf("输入新烹饪时间(分钟): "); scanf("%d", &target->cooking_time); getchar(); break; case 9: get_lovers(target->lovers, &target->lover_count); break; default: printf("无效选择\n"); } printf("\n修改后的菜谱:\n"); print_recipe(target); } // 查找菜谱 void search_recipes() { printf("1. 按ID查找\n2. 按名称查找\n3. 按餐型查找\n"); printf("4. 按口味查找\n5. 按状态查找\n6. 按菜系查找\n"); printf("7. 显示全部\n选择查找方式: "); int choice; scanf("%d", &choice); getchar(); Recipe* current = recipe_list; int found = 0; switch(choice) { case 1: { printf("输入菜谱ID: "); int id; scanf("%d", &id); getchar(); Recipe* target = find_recipe_by_id(id); if (target) { print_recipe(target); found = 1; } break; } case 2: { printf("输入菜名: "); char name[MAX_NAME_LEN]; fgets(name, MAX_NAME_LEN, stdin); name[strcspn(name, "\n")] = '\0'; Recipe* target = find_recipe_by_name(name); if (target) { print_recipe(target); found = 1; } break; } case 3: { MealType meal_type; get_meal_type(&meal_type); while (current) { if (current->meal_type == meal_type) { print_recipe(current); found = 1; } current = current->next; } break; } case 4: { int taste_flags; const char* tastes[] = {"酸", "甜", "苦", "辣", "咸", "凉", "热"}; get_multi_select_options("选择口味", &taste_flags, tastes, 7); while (current) { if ((current->taste_flags & taste_flags) == taste_flags) { print_recipe(current); found = 1; } current = current->next; } break; } case 5: { int state_flags; const char* states[] = {"汤", "干", "湿", "脆", "软", "硬"}; get_multi_select_options("选择状态", &state_flags, states, 6); while (current) { if ((current->state_flags & state_flags) == state_flags) { print_recipe(current); found = 1; } current = current->next; } break; } case 6: { Cuisine cuisine; get_cuisine(&cuisine); while (current) { if (current->cuisine == cuisine) { print_recipe(current); found = 1; } current = current->next; } break; } case 7: while (current) { print_recipe(current); current = current->next; found = 1; } break; } if (!found) { printf("未找到匹配的菜谱!\n"); } } // 随机推荐 void random_recommendation() { printf("1. 推荐一餐\n2. 推荐多天餐食\n选择: "); int choice; scanf("%d", &choice); getchar(); srand(time(NULL)); if (choice == 1) { MealType meal_type; get_meal_type(&meal_type); int count; printf("输入推荐数量: "); scanf("%d", &count); getchar(); // 收集符合条件的菜谱 Recipe* candidates[MAX_RECIPES]; int candidate_count = 0; Recipe* current = recipe_list; while (current) { if (current->meal_type == meal_type) { candidates[candidate_count++] = current; } current = current->next; } if (candidate_count == 0) { printf("没有符合条件的菜谱!\n"); return; } printf("\n推荐菜谱:\n"); for (int i = 0; i < count && i < candidate_count; i++) { int idx = rand() % candidate_count; print_recipe(candidates[idx]); // 避免重复推荐 candidates[idx] = candidates[--candidate_count]; } } else if (choice == 2) { int days; printf("输入天数: "); scanf("%d", &days); getchar(); // 每种餐型所需数量 int counts[5] = {0}; const char* meals[] = {"早餐", "正餐(午)", "正餐(晚)", "甜品", "零食", "饮品"}; for (int i = 0; i < 5; i++) { if (i == 1) // 正餐需要两次 { printf("%s数量: ", meals[1]); scanf("%d", &counts[1]); printf("%s数量: ", meals[2]); scanf("%d", &counts[2]); } else { printf("%s数量: ", meals[i + (i>1?1:0)]); scanf("%d", &counts[i]); } } getchar(); // 按天生成餐单 for (int day = 1; day <= days; day++) { printf("\n=== 第 %d 天 ===\n", day); // 收集每种餐型的菜谱 Recipe* meal_candidates[5][MAX_RECIPES]; int meal_counts[5] = {0}; Recipe* current = recipe_list; while (current) { if (current->meal_type == BREAKFAST) { meal_candidates[0][meal_counts[0]++] = current; } else if (current->meal_type == MAIN_COURSE) { meal_candidates[1][meal_counts[1]++] = current; meal_candidates[2][meal_counts[2]++] = current; } else if (current->meal_type == DESSERT) { meal_candidates[3][meal_counts[3]++] = current; } else if (current->meal_type == SNACK) { meal_candidates[4][meal_counts[4]++] = current; } else if (current->meal_type == DRINK) { meal_candidates[5][meal_counts[5]++] = current; } current = current->next; } // 生成当天的每种餐型 for (int meal = 0; meal < 6; meal++) { int meal_idx = meal; if (meal > 1) meal_idx--; // 调整索引 if (counts[meal_idx] == 0) continue; printf("\n%s:\n", meals[meal]); for (int i = 0; i < counts[meal_idx]; i++) { if (meal_counts[meal] == 0) { printf(" (无足够菜谱)\n"); break; } int idx = rand() % meal_counts[meal]; printf(" - %s\n", meal_candidates[meal][idx]->name); // 避免重复 meal_candidates[meal][idx] = meal_candidates[meal][--meal_counts[meal]]; } } } } } main.c文件: #include <stdio.h> #include <stdlib.h> #include "data.h" #include "recipe.h" #include "file.h" #include <windows.h> // 添加 Windows API 支持 // 全局变量 Recipe* recipe_list = NULL; int recipe_count = 0; char lovers_list[MAX_LOVERS][MAX_NAME_LEN]; int lover_count = 0; void display_main_menu() { 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("请选择操作: "); } void lover_management() { printf("\n喜好者管理\n"); printf("1. 添加喜好者\n"); printf("2. 删除喜好者\n"); printf("3. 查看所有喜好者\n"); printf("请选择操作: "); int choice; scanf("%d", &choice); getchar(); // 消耗换行符 switch(choice) { case 1: if (lover_count < MAX_LOVERS) { printf("输入喜好者姓名: "); fgets(lovers_list[lover_count], MAX_NAME_LEN, stdin); lovers_list[lover_count][strcspn(lovers_list[lover_count], "\n")] = '\0'; lover_count++; save_lovers(); printf("添加成功!\n"); } else { printf("喜好者数量已达上限!\n"); } break; case 2: printf("当前喜好者:\n"); for (int i = 0; i < lover_count; i++) { printf("%d. %s\n", i+1, lovers_list[i]); } printf("选择要删除的编号: "); int idx; scanf("%d", &idx); getchar(); if (idx > 0 && idx <= lover_count) { for (int i = idx-1; i < lover_count-1; i++) { strcpy(lovers_list[i], lovers_list[i+1]); } lover_count--; save_lovers(); printf("删除成功!\n"); } else { printf("无效选择!\n"); } break; case 3: printf("所有喜好者:\n"); for (int i = 0; i < lover_count; i++) { printf("%d. %s\n", i+1, lovers_list[i]); } break; } } int main() { // 设置控制台编码为 UTF-8 SetConsoleOutputCP(65001); SetConsoleCP(65001); load_data(); load_lovers(); int running = 1; while (running) { display_main_menu(); int choice; scanf("%d", &choice); getchar(); // 消耗换行符 switch(choice) { case 1: add_recipe(); break; case 2: delete_recipe(); break; case 3: modify_recipe(); break; case 4: search_recipes(); break; case 5: random_recommendation(); break; case 6: lover_management(); break; case 7: save_data(); running = 0; break; default: printf("无效选择!\n"); } } return 0; } makefile文件 CC = g++ CFLAGS = -Wall -Wextra -std=c++11 -g TARGET = wj SOURCES = main.c recipe.c file.c HEADERS = data.h recipe.h file.h all: $(TARGET) $(TARGET): $(SOURCES) $(HEADERS) $(CC) $(CFLAGS) -o $(TARGET) $(SOURCES) clean: rm -f $(TARGET) *.dat run: $(TARGET) ./$(TARGET) .PHONY: all clean run 消化这些代码文件,稍后我会给出修改要求
07-28
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值