C语言读取文本文件分数并存入数组求和遇阻,求解决方案
问题解决建议与分数求和实现思路
一、读取分数数组的问题修正
你的代码存在几处编译和逻辑错误,以下是具体修正点及修正后的代码:
错误点分析
- 函数未提前声明:
fillArray在main调用前未声明,编译会报错。 - 文件指针变量名不匹配:声明
FILE *txt;却使用fp操作,变量名不一致。 fscanf参数错误:读取结构体成员需要传递地址,直接传值会导致写入失败。- 循环条件错误:
while(!feof(fp))会导致最后一次循环多读无效数据,应使用fscanf的返回值判断读取是否成功。 - 数组越界风险:未限制
i不超过数组容量N,可能导致内存溢出。 - 文件打开失败未处理:未判断
fopen是否成功,若文件不存在会直接崩溃。 - 函数返回值缺失:
fillArray声明返回int但无返回语句。
修正后的代码
#include <stdio.h> #include <stdlib.h> #define N 20 // 测试用数组容量 typedef struct{ int numerator; int denominator; }TFraction; // 提前声明函数 int fillArray(TFraction A[]); int main(){ TFraction F[N]; int count = fillArray(F); printf("成功读取%d个分数\n", count); return 0; } int fillArray(TFraction A[]){ FILE *fp; char skip; int i = 0; fp = fopen("fractions.txt", "r"); // 检查文件是否打开成功 if(fp == NULL){ printf("无法打开文件\n"); return 0; } // 用fscanf返回值判断是否成功读取3个元素,同时限制数组不越界 while(i < N && fscanf(fp, "%d%c%d", &A[i].numerator, &skip, &A[i].denominator) == 3){ // 确保分母不为0,若文件中出现分母为0的情况,跳过该分数 if(A[i].denominator == 0){ printf("警告:第%d个分数分母为0,已跳过\n", i+1); continue; } i++; } fclose(fp); // 返回实际读取的分数个数 return i; }
二、分数求和与化简实现思路
1. 分数求和逻辑
遍历数组中的每个分数,依次与当前结果相加,分数相加的公式为:
若当前结果为
res_num/res_den,待加分数为num/den,则相加后结果为:(res_num * den + num * res_den) / (res_den * den)
2. 分数化简方法
每次相加后需对结果分数进行化简,核心是计算分子分母的最大公约数(GCD),步骤如下:
- 用欧几里得算法计算分子绝对值与分母绝对值的GCD。
- 将分子和分母同时除以GCD,得到最简分数。
- 确保分母为正:若分母为负,将分子和分母同时取反。
3. 关键函数实现
最大公约数(GCD)函数
// 计算两个整数的最大公约数,欧几里得算法 int gcd(int a, int b){ a = abs(a); b = abs(b); while(b != 0){ int temp = b; b = a % b; a = temp; } return a; }
分数化简函数
// 化简分数,确保分母为正 void simplify(TFraction *frac){ if(frac->denominator == 0){ printf("错误:分母不能为0\n"); return; } int common_divisor = gcd(frac->numerator, frac->denominator); frac->numerator /= common_divisor; frac->denominator /= common_divisor; // 确保分母为正 if(frac->denominator < 0){ frac->numerator = -frac->numerator; frac->denominator = -frac->denominator; } }
分数求和函数
TFraction sumFractions(TFraction fractions[], int count){ TFraction result = {0, 1}; // 初始结果为0/1 for(int i = 0; i < count; i++){ // 计算分子:res_num*den + num*res_den int new_num = result.numerator * fractions[i].denominator + fractions[i].numerator * result.denominator; // 计算分母:res_den*den int new_den = result.denominator * fractions[i].denominator; result.numerator = new_num; result.denominator = new_den; simplify(&result); // 每次相加后化简 } return result; }
4. 主函数中调用求和
在main函数中添加调用逻辑:
int main(){ TFraction F[N]; int count = fillArray(F); if(count == 0){ return 1; } TFraction total = sumFractions(F, count); printf("所有分数求和结果:%d/%d\n", total.numerator, total.denominator); return 0; }
内容的提问来源于stack exchange,提问作者Sergio Alejandro Vazquez Rodrg
相关产品推荐
相关产品推荐

