C语言读取温度文本文件计算最值及平均值时程序崩溃问题求助
问题分析与修复方案
我帮你排查了代码里的几个关键问题,其中最直接导致崩溃的是文件打开逻辑的错误,还有其他几个潜在的bug也需要修正:
1. 导致崩溃的核心问题:文件打开循环条件写反
你这段代码的循环逻辑完全搞反了:
do { printf("Enter File name: \n"); fflush(stdout); scanf("%s", eingabe); fp = fopen(eingabe, "r" ); if(fp == NULL) printf ("Error: File %s can't be opened!\n", eingabe); }while(fp != NULL);
当前逻辑是文件打开成功时继续循环,会一直让你输入文件名,直到你输入一个不存在的文件(此时fp == NULL)才退出循环。后续代码用NULL的文件指针去读取数据,必然触发程序崩溃!
修复方案:把循环条件改成while(fp == NULL),也就是打开失败时重试,打开成功就退出循环。
2. 其他潜在问题与修复
温度数量的存储逻辑不严谨
你把温度数量存在temperatur[0],再转成int返回,容易出现精度问题。应该单独用int变量存储数量,同时调整数组的使用方式(数据从temperatur[0]开始存储,避免和数量混在一起):
int ReadTempFile(FILE *fp, float temperatur[]) { int count; // 先读取温度数量 if (fscanf(fp, "%d", &count) != 1) { // 读取失败或文件结束,返回0表示无数据 return 0; } // 防止数组越界(temperatur数组大小为20,最多存19个数据) if(count > 19){ printf("Warning: Too many temperature values, only reading first 19.\n"); count = 19; } // 读取count个温度数据 for(int i = 0; i < count; ++i) { fscanf(fp, "%f", &temperatur[i]); } return count; }
平均温度计算的错误
你的mittlereTemp函数有两个明显问题:
sum是int类型,累加float温度会丢失小数精度,应该改成float- 错误地把存储数量的
temperatur[0]也加入了求和,且分母应该用传入的anzahl参数
修复后的函数:
float mittlereTemp(int anzahl, float temperatur[]) { int i; float sum = 0.0; float mit; for (i = 0; i < anzahl; i++) { sum += temperatur[i]; } mit = sum / anzahl; return mit; }
最大/最小温度函数的索引越界
原来的maxTemp和minTemp函数中,循环访问temperatur[i+1]会导致索引越界,修复后直接使用正确的数组下标:
float maxTemp(int anzahl, float temperatur[]) { float max = temperatur[0]; for(int i = 1; i < anzahl; i++) { if(temperatur[i] > max) { max = temperatur[i]; } } return max; } float minTemp(int anzahl, float temperatur[]) { float min = temperatur[0]; for(int i = 1; i < anzahl; i++) { if(temperatur[i] < min) { min = temperatur[i]; } } return min; }
文件读取循环的终止条件优化
用feof(fp)判断终止不可靠,应该通过ReadTempFile的返回值判断是否还有数据:
do{ n = ReadTempFile(fp, temperatur); if(n == 0){ break; // 无数据则退出循环 } // 输出计算结果的代码 }while (1);
完整修复后的代码
#include<stdio.h> #include<string.h> int ReadTempFile(FILE *fp, float temperatur[]); float maxTemp(int anzahl, float temperatur[]); float minTemp(int anzahl, float temperatur[]); float mittlereTemp(int anzahl, float temperatur[]); float fahrenheit(float celsius); int ReadTempFile(FILE *fp, float temperatur[]) { int count; if (fscanf(fp, "%d", &count) != 1) { return 0; } if(count > 19){ printf("Warning: Too many temperature values, only reading first 19.\n"); count = 19; } for(int i = 0; i < count; ++i) { fscanf(fp, "%f", &temperatur[i]); } return count; } float maxTemp(int anzahl, float temperatur[]) { float max = temperatur[0]; for(int i = 1; i < anzahl; i++) { if(temperatur[i] > max) { max = temperatur[i]; } } return max; } float minTemp(int anzahl, float temperatur[]) { float min = temperatur[0]; for(int i = 1; i < anzahl; i++) { if(temperatur[i] < min) { min = temperatur[i]; } } return min; } float mittlereTemp(int anzahl, float temperatur[]) { int i; float sum = 0.0; float mit; for (i = 0; i < anzahl; i++) { sum += temperatur[i]; } mit = sum / anzahl; return mit; } float fahrenheit(float celsius) { float f; f = (celsius*9/5.0) + 32; // 用5.0避免整数除法 return f; } int main() { int n, Zeile=1; float temperatur[20], max, min, mit, fmax, fmin, fmit; char eingabe[20]; FILE *fp=NULL; // 修复文件打开循环条件 do { printf("Enter File name: \n"); fflush(stdout); scanf("%s", eingabe); fp = fopen(eingabe, "r" ); if(fp == NULL) printf ("Error: File %s can't be opened!\n", eingabe); }while(fp == NULL); do{ n = ReadTempFile(fp, temperatur); if(n == 0){ break; } max = maxTemp(n, temperatur); printf("Das Maximum der Zeile %d ist: %.3fC \t",Zeile, max); fmax = fahrenheit(max); printf("In Fahrenheit: %.3fF\n", fmax); min = minTemp(n, temperatur); printf("Das Minimum der Zeile %d ist: %.3fC \t",Zeile, min); fmin = fahrenheit(min); printf("In Fahrenheit: %.3fF\n", fmin); mit = mittlereTemp(n, temperatur); printf("Der Mittelwert der Zeile %d ist: %.3fC \t",Zeile, mit); fmit = fahrenheit(mit); printf("In Fahrenheit: %.3fF\n", fmit); ++Zeile; printf("\n\n"); }while (1); fclose(fp); return 0; }
测试说明
针对你的Temp.txt内容,程序会按以下逻辑处理:
- 读取第一个数5,然后读取后面5个温度:76,56,34,35,10
- 计算并输出这组数据的最大、最小、平均温度及对应华氏度
- 继续读取下一个数4,然后读取4个温度:45,23,24,14
- 重复计算输出,直到文件所有数据处理完成
内容的提问来源于stack exchange,提问作者Hilfe
相关产品推荐
相关产品推荐

