结构体文件匹配筛选问题:仅输出首个匹配项,求解决方法
问题分析与修复
你的代码只输出第一个匹配项的核心原因是:读取完一次Votes.dat后,文件指针停在了文件末尾,后续循环无法再读取任何投票数据。
具体来说,你仅在循环开始前调用了一次rewind(vfp),第一次遍历候选人时,内层循环会把Votes.dat的文件指针移到末尾。之后处理下一个候选人时,内层的fread直接返回0,不会执行任何匹配检查。
修复步骤
- 每次处理新候选人时重置投票文件指针:将
rewind(vfp)移到外层循环内部、内层循环之前,确保每个候选人都能从头扫描Votes.dat。 - 添加文件打开失败的错误检查:避免文件无法打开时出现未定义行为。
- 关闭文件资源:操作完成后关闭打开的文件,释放系统资源。
- 优化输出格式:添加换行符让输出结构更清晰。
修正后的代码
#include <stdio.h> #include <stdlib.h> // 你的结构体定义 struct candidate { char fullName[50]; char email[50]; char division[20]; int age; int voter_num; char citizenship_no[15]; char district[20]; char party[20]; char post[20]; char sex; int province_num; }; struct votes { int voter_num; int total_votes; }; int main() { struct candidate candi; FILE *cfp = fopen("Candidates.dat", "rb+"); // 检查候选人文件是否成功打开 if (cfp == NULL) { perror("无法打开Candidates.dat文件"); return EXIT_FAILURE; } FILE *vfp = fopen("Votes.dat", "rb+"); // 检查投票文件是否成功打开 if (vfp == NULL) { perror("无法打开Votes.dat文件"); fclose(cfp); // 关闭已打开的候选人文件 return EXIT_FAILURE; } struct votes display_votes; while (fread(&candi, sizeof(struct candidate), 1, cfp)) { // 每次处理新候选人时,重置投票文件指针到开头 rewind(vfp); while (fread(&display_votes, sizeof(struct votes), 1, vfp)) { if (candi.voter_num == display_votes.voter_num) { printf("-----------\n"); printf("|District:-%s\t\t Province Number:%d\n", candi.district, candi.province_num); printf("-----------\n\n"); printf("-----------------------------------------------------------------------------------\n"); printf("Voter-Num\tCandidate\t\tParty\t\tPost\t\tTotal-Votes\n"); printf("-----------------------------------------------------------------------------------\n"); printf("%d%18s%22s%18s%15d\n", display_votes.voter_num, candi.fullName, candi.party, candi.post, display_votes.total_votes); printf("\n"); // 添加换行分隔不同候选人的结果 } } } // 关闭所有打开的文件 fclose(cfp); fclose(vfp); return EXIT_SUCCESS; }
额外优化建议
如果数据量较大,这种逐行比对的效率会比较低。可以考虑先将Votes.dat中的数据加载到内存哈希表中(以voter_num为键),后续匹配时只需O(1)的查找时间,整体运行效率会大幅提升。
内容的提问来源于stack exchange,提问作者Gunaraj Khatri
相关产品推荐
相关产品推荐

