C程序读取浮点文件行数后计算异常,请求排查错误原因
问题分析与修复
核心错误点
- 文件指针未重置:统计行数后指针已到文件末尾,后续读取无数据
- 缓冲区溢出:字符串存储数组维度错误,写入越界触发未定义行为
- 行数统计逻辑漏洞:仅统计换行符会遗漏无换行的最后一行
- 冗余数据转换:没必要先读字符串再转浮点数,增加出错风险
错误详情与修复方案
文件指针位置问题
统计行数的循环会把文件指针移动到EOF位置,后续fscanf无法读取任何内容,strtod转换无效数据得到0.0,导致输出全为0。
修复:统计完成后调用rewind(fptr)将指针重置回文件开头,或使用fseek(fptr, 0, SEEK_SET)。数组维度错误
char arrayNum[count];是一维字符数组,每个元素仅能存单个字符,但fscanf("%s", &arrayNum[i])会尝试把整行浮点数字符串写入该地址,直接触发缓冲区溢出,可能导致程序挂起或崩溃。
修复:要么用二维字符数组(如char arrayNum[count][64];)存储每行字符串,更高效的方式是直接读取double类型,跳过字符串转换步骤。行数统计逻辑漏洞
原代码通过统计\n数量计数行数,若文件最后一行无换行符,统计结果会比实际行数少1。
修复:初始将count设为1(默认至少有一行),遇到换行符再递增;或统计完成后检查文件末尾是否为换行符,若非则额外加1。冗余数据转换
fscanf支持直接用%lf格式符读取浮点数值,无需先读字符串再转double,简化代码同时避免转换错误。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <math.h> int main() { FILE *fptr; int count = 1; // 初始化为1,兼容最后一行无换行的情况 char ch; // 打开文件 if ((fptr = fopen("C:\\Users\\Evandovich\\Desktop\\White_Noise.txt", "r")) == NULL) { printf("Error! opening file"); exit(1); } // 统计文件行数 for (ch = getc(fptr); ch != EOF; ch = getc(fptr)) { if (ch == '\n') { count++; } } printf("The file has %d lines\n", count); // 重置文件指针到开头 rewind(fptr); // 存储计算结果的数组 double result1[count]; // 读取数值并计算平方 for (int i = 0; i < count; i++) { double val; fscanf(fptr, "%lf", &val); result1[i] = pow(val, 2); printf("value %.6f\n", result1[i]); } fclose(fptr); return 0; }
内容的提问来源于stack exchange,提问作者Afro77
相关产品推荐
相关产品推荐

