You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:30:50