栈pop()函数未正确弹出元素?数据丢失问题求助
栈实现中的数据丢失问题排查
问题根源分析
输入文件中的PAP313数据未出现在输出文件,核心原因有两点:
1. 栈容量不足导致数据未被加载
你的栈结构体struct report中,storage数组的大小为N_STACK=4,但输入文件包含5条车辆数据。load_vehicles_from_file函数调用push时未处理返回值:当栈内元素达到4个后,push会返回FULL状态,但代码直接忽略了这个结果,导致第5条数据PAP313完全没有被压入栈,自然无法在后续处理中被读取。
2. 栈遍历逻辑不合理
write_crimes_on_file中使用固定循环次数for (int i=0; i<N_STACK; i++)执行pop,这会强制执行4次弹出操作,即便栈内实际元素数量不足(比如后续调整栈容量后,若最后一次pop返回EMPTY,代码也未做处理)。不过当前问题的核心还是数据未被加载入栈。
修复方案
方案一:扩大栈容量
将N_STACK调整为足够容纳所有输入数据的数值(例如8),确保所有车辆数据都能被压入栈:
#define N_STACK 8 // 修改为更大的数值
方案二:处理栈满的情况
修改load_vehicles_from_file函数,检查push的返回值,当栈满时给出提示或做相应处理:
int load_vehicles_from_file(char* filename, struct report* stack) { FILE* fp = fopen(filename, "r"); if (fp == NULL) return FILE_ERR; struct vehicle s; while (fscanf(fp, "%s%lf%lf", s.plate, &s.speed, &s.limit) == 3) { int ret = push(stack, s); // 直接使用stack指针,无需&(*stack) if (ret == FULL) { printf("栈已满,无法加载数据:%s\n", s.plate); // 可根据需求选择退出循环或继续跳过后续数据 // break; } } fclose(fp); return OK; }
方案三:基于实际元素数量遍历栈
替换固定次数的循环,改为根据栈内实际元素数量n_busy执行pop,避免无效操作:
int write_crimes_on_file(char* filename, struct report* stack) { FILE* fp = fopen(filename, "w"); if (fp == NULL) return FILE_ERR; double fine; struct vehicle s; // 循环pop直到栈为空 while (pop(stack, &s) == OK) { double exceed = s.speed - (s.limit * 1.05); if (exceed > 0) { // 直接判断超速,避免修改原结构体数据 fine = charge_crime(exceed); fprintf(fp, "%s\t%.1f %.1f\n", s.plate, exceed, fine); } } fclose(fp); return OK; }
额外优化:避免修改原始数据
原is_crime函数会修改struct vehicle的limit成员(替换为超速差值),这会破坏原始数据。建议直接在逻辑中计算超速差值,不修改结构体:
// 可以移除原is_crime函数,直接在write时判断 // 或者修改为返回超速差值的函数: double calculate_exceed(struct vehicle* s) { return s->speed - (s->limit * 1.05); }
验证PAP313的超速情况
PAP313的速度为95.0,限速90.0,5%容忍度对应的阈值是90*1.05=94.5,95.0>94.5,属于超速。修复栈容量后,该数据会被正常加载并输出到结果文件中。
内容的提问来源于stack exchange,提问作者sansarc
相关产品推荐
相关产品推荐

