C语言读取CSV提取不及格学生ID失败:输入文件名后程序终止排查
问题排查:读取CSV文件时程序卡顿的原因及修复
我需要提取考试不及格(score<60)学生的ID,写了下面的C语言代码,但输入文件名后程序就停住了,没法继续执行。帮忙看看哪里出问题,代码和CSV输入文件如下:
原代码
#include<stdio.h> #include<stdlib.h> #include<string.h> int main(){ int i=0, j=0, count=0; int id[500], score[500], fail[500]; char fname1[128], rbsh[100]; scanf("%s", fname1); FILE *f1 = fopen(fname1, "r"); fscanf(f1, "%s", rbsh); while(1){ fscanf(f1, "%d ", &id[i]); fscanf(f1, "%d\n", &score[i]); i++; count++; if(feof(f1)){ break; } } fclose(f1); for(i=0; i<count; i++){ if(score[i]<60){ fail[j] = id[i]; j++; } } for(i=0; i<j; i++){ printf("%d ", fail[i]); } return 0; }
CSV输入文件内容
ID,score 1,25 2,77 3,88 4,100 5,100 6,44 7,10 8,69 9,70 10,35 11,69
问题分析
- 文件打开未做错误校验:如果输入的文件名错误、文件不存在或无读取权限,
fopen会返回NULL,直接操作空指针会导致程序卡死或崩溃。 - 数据读取格式不匹配:CSV每行的格式是
数字,数字,原代码用fscanf(f1, "%d ", &id[i])读取ID时,会跳过空白符但不会处理逗号,导致程序一直等待下一个数字,彻底卡住。后续的%d\n也多余,换行符会被fscanf自动跳过,但逗号没处理的话根本读不到分数。 - feof的使用时机错误:
feof要在读取操作之后判断,原代码先执行读取再检查,但如果读取失败(比如格式不匹配),feof不会触发,会进入死循环。
修复后的代码
#include<stdio.h> #include<stdlib.h> #include<string.h> int main(){ int i=0, j=0, count=0; int id[500], score[500], fail[500]; char fname1[128], rbsh[100]; scanf("%s", fname1); FILE *f1 = fopen(fname1, "r"); // 检查文件是否成功打开 if(f1 == NULL){ printf("无法打开指定文件!\n"); return 1; } // 读取表头("ID,score") fscanf(f1, "%s", rbsh); // 按CSV格式读取每行数据,判断是否成功读取两个整数 while(fscanf(f1, "%d,%d", &id[i], &score[i]) == 2){ i++; count++; } fclose(f1); for(i=0; i<count; i++){ if(score[i]<60){ fail[j] = id[i]; j++; } } for(i=0; i<j; i++){ printf("%d ", fail[i]); } printf("\n"); return 0; }
关键修改说明
- 新增文件打开失败的判断,避免空指针操作;
- 调整数据读取格式为
%d,%d,完美匹配CSV的数字,数字结构,无需额外处理空格或换行; - 用
fscanf的返回值(成功读取的变量数)作为循环终止条件,替代feof,彻底避免死循环; - 结尾添加换行符,让输出更整洁。
内容的提问来源于stack exchange,提问作者せいが
相关产品推荐
相关产品推荐

