C语言队列与结构体实现票务系统的代码问题求助
你的C语言票务系统问题排查与修复方案
我仔细检查了你的代码,发现了几个关键问题导致系统无法正常工作,下面逐一分析并给出修复后的完整实现:
主要问题梳理
- 结构体存储错误:你只定义了单个
struct ticket_details变量,但要存储多张票务信息,必须用结构体数组才行 - 菜单选项匹配错误:
switch里写的是字符常量'1',但scanf读取的是整数类型,导致所有选项都会触发default分支 - 队列与结构体关联逻辑混乱:
items数组完全冗余,直接用队列的front/rear指针管理结构体数组的索引就够了 - printf语法错误:
display和search函数里的printf写法完全错误,不能用+拼接格式字符串和变量,这会导致编译报错 - 删除功能逻辑错误:
deQueue函数误用free(free只能释放堆内存,这里的变量都在栈上),而且删除逻辑完全不符合队列的操作逻辑 - 菜单仅执行一次:当前代码选完选项就直接退出,应该用循环让用户重复操作
- 搜索逻辑错误:循环中只要当前元素不匹配就输出"未找到",这会导致第一个不匹配就提示错误,正确逻辑是遍历完所有元素都没匹配才提示
修复后的完整代码
#include <stdio.h> #define SIZE 100 // 函数声明 void enQueue(); void deQueueByID(int ticket_id); void displayAll(); void searchByID(int ticket_id); // 票务信息结构体定义 struct ticket_details { int ticket_id; char name[20]; int age; char movie[50]; }; // 结构体数组存储所有票务信息 struct ticket_details tickets[SIZE]; // 队列的头尾指针 int front = -1; int rear = -1; // 全局自增的票务ID,确保每个票务唯一 int next_ticket_id = 1; int main() { int choice = 0; // 循环显示菜单,直到用户选择退出 while (1) { printf("\n===== 简易票务系统 =====\n"); printf("1. 购买新票务(入队)\n"); printf("2. 检索单条票务\n"); printf("3. 显示所有票务\n"); printf("4. 删除指定票务\n"); printf("5. 退出系统\n"); printf("请输入你的选择:"); scanf("%d", &choice); switch(choice) { case 1: enQueue(); break; case 2: { int search_id; printf("请输入要检索的票务ID:"); scanf("%d", &search_id); searchByID(search_id); break; } case 3: displayAll(); break; case 4: { int delete_id; printf("请输入要删除的票务ID:"); scanf("%d", &delete_id); deQueueByID(delete_id); break; } case 5: printf("感谢使用票务系统,再见!"); return 0; default: printf("输入无效,请重新选择!\n"); } } } // 添加新票务(入队操作) void enQueue() { if (rear == SIZE - 1) { printf("\n抱歉,票务容量已满,无法添加新票务!\n"); return; } // 首次入队时初始化队头指针 if (front == -1) { front = 0; } rear++; // 为当前票务分配唯一ID tickets[rear].ticket_id = next_ticket_id++; printf("\n请输入票务信息:\n"); printf("姓名:"); scanf("%s", tickets[rear].name); printf("年龄:"); scanf("%d", &tickets[rear].age); printf("喜爱的电影:"); scanf("%s", tickets[rear].movie); printf("\n票务添加成功!你的票务ID是:%d\n", tickets[rear].ticket_id); } // 根据票务ID删除(注:标准队列是FIFO删除,这里实现按ID删除以满足需求) void deQueueByID(int ticket_id) { if (front == -1) { printf("\n当前没有任何票务,无法执行删除操作!\n"); return; } int i, found = 0; // 遍历队列查找目标票务 for (i = front; i <= rear; i++) { if (tickets[i].ticket_id == ticket_id) { found = 1; break; } } if (!found) { printf("\n未找到ID为%d的票务!\n", ticket_id); return; } // 移动后续元素覆盖被删除的位置 for (; i < rear; i++) { tickets[i] = tickets[i+1]; } rear--; // 如果删除后队列为空,重置头尾指针 if (front > rear) { front = rear = -1; } printf("\nID为%d的票务已成功删除!\n", ticket_id); } // 显示所有票务信息 void displayAll() { if (front == -1) { printf("\n当前没有任何票务记录!\n"); return; } printf("\n===== 所有票务信息 =====\n"); for (int i = front; i <= rear; i++) { printf("票务ID:%d\n", tickets[i].ticket_id); printf("姓名:%s\n", tickets[i].name); printf("年龄:%d\n", tickets[i].age); printf("喜爱的电影:%s\n", tickets[i].movie); printf("------------------------\n"); } } // 根据ID检索指定票务 void searchByID(int ticket_id) { if (front == -1) { printf("\n当前没有任何票务记录!\n"); return; } int found = 0; for (int i = front; i <= rear; i++) { if (tickets[i].ticket_id == ticket_id) { found = 1; printf("\n===== 检索到的票务信息 =====\n"); printf("票务ID:%d\n", tickets[i].ticket_id); printf("姓名:%s\n", tickets[i].name); printf("年龄:%d\n", tickets[i].age); printf("喜爱的电影:%s\n", tickets[i].movie); break; } } if (!found) { printf("\n未找到ID为%d的票务!\n", ticket_id); } }
关键修复说明
- 结构体数组替换单个变量:用
tickets[SIZE]存储多张票务,解决了无法存储多条信息的问题 - 菜单循环实现:通过
while(1)让用户可以重复操作菜单,直到主动退出 - 修正printf语法:把错误的格式字符串拼接方式改成标准的
printf("格式", 变量1, 变量2...)写法 - 优化队列逻辑:去掉冗余的
items数组,直接用front和rear管理结构体数组的索引,逻辑更清晰 - 正确的删除逻辑:实现按ID查找并删除,同时处理队列为空的边界情况,避免崩溃
- 修复搜索逻辑:遍历完所有元素后才判断是否找到,避免中途误判
- 选项匹配修正:
switch中使用整数常量(如case 1),和scanf读取的整数类型匹配,确保选项能正确触发
内容的提问来源于stack exchange,提问作者medoleader91
相关产品推荐
相关产品推荐

