C语言读取txt输入文件获得错误值问题求助
C语言成绩统计程序数据异常问题解答
核心错误根因
你遇到的所有异常都是数组越界访问、写入地址错误导致的,和换行符处理无关:fscanf读取%d、%s格式符时默认跳过所有前置空白字符(包括空格、换行、制表符),无需额外处理换行。
1. getStudents函数错误(核心根源)
原有代码存在两个严重错误:
- 循环起始值设为
i=-1属于非法内存访问,会写入students[-1]的栈空间,直接覆盖栈上其他变量(包括grades数组的首元素),这是grades[0][0]出现随机值的核心原因之一。 - 写入地址错误:
&students[i][NAME_LENGTH]是每个姓名字符串数组的末尾后第一个字节的地址,刚好等于下一个学生姓名数组的起始地址,会导致读取的姓名全部错位存储。比如i=0时写入的内容会存在students[1]的位置,你不得不把i设为-1才能把第一个姓名存到students[0],本质是错误的越界操作。
修正后的getStudents代码:
void getStudents(FILE *ifp, int stus, char students[stus][NAME_LENGTH]) { int i = 0; // 正常从0开始循环,循环次数等于学生数 for (i = 0; i < stus; ++i) { // 直接传入每个姓名数组的起始地址即可 fscanf(ifp, "%s", students[i]); } }
2. getGrades函数错误
原有代码使用j+1作为下标,会跳过grades[i][0]的位置,导致该位置从未被赋值,保留栈内存的初始随机值,同时当j = stus-1时j+1 = stus,又会触发数组越界写入。你之前加j+1只是为了匹配前面getStudents错位读取多消耗了第一个成绩的问题,属于用错误掩盖错误。
修正后的getGrades代码:
void getGrades(FILE *ifp, int assigns, int stus, int grades[assigns][stus]) { int i = 0, j = 0; for (i = 0; i < assigns; ++i) { for (j = 0; j < stus; ++j) { // 直接使用j作为下标即可,不需要+1 fscanf(ifp, "%d", &grades[i][j]); } } }
3. main函数次要错误
原有代码把文件名写死为input.txt,没有使用命令行传入的argv[1]参数,修正为:
ifp = fopen(argv[1], "r");
疑问对应解答
grades[0][0]为随机值的原因:一是getStudents的越界写入覆盖了该位置的值,二是getGrades没有给该位置赋值,两个问题叠加导致。- 不需要再加
j+1,修正getStudents函数的读取逻辑后,直接使用j作为下标即可正常对齐所有成绩数据。 - 不需要把循环起始值设为
i=-1,修正写入地址后即可从i=0正常读取全部5个学生姓名,不会出现数据偏移。
内容的提问来源于stack exchange,提问作者Koussevitzky
相关产品推荐
相关产品推荐

