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

读取score.txt文件中int数组失败,如何修复代码错误?

问题描述

读取score.txt文件中的int数组时触发错误,错误提示为:$ !ERROR: Wrong file format to 'score.txt',怀疑问题出在读取int score[3]的代码段,相关代码与文件内容如下:

C代码

// code

typedef struct {
    int no;
    char name[TSIZE];
    int score[3];
    int sum;
    double avg;
} Score;

int num;
    if (fscanf(file, "%d%*c", &num) != 1){
        printf("$ !ERROR: Wrong file format to num.\n");
        exit(1);
    }

    *ptr_s_list = (Score *)malloc(sizeof(Score) * num);
    if (*ptr_s_list == NULL){
        printf("$ !ERROR: Malloc failed.\n");
        exit(1);
    }

    for (int s = 0; s < num; ++s){
        if (fscanf(file, "%d%*c", &(*ptr_s_list)[*ptr_s_items].no) != 1
        || fscanf(file, "%[^\n]%*c", (*ptr_s_list)[*ptr_s_items].name) != 1
        || fscanf(file, "%d %d %d", &(*ptr_s_list)[*ptr_s_items].score[0], &(*ptr_s_list)[*ptr_s_items].score[1], &(*ptr_s_list)[*ptr_s_items].score[2]) != 1
        || fscanf(file, "%d%*c", &(*ptr_s_list)[*ptr_s_items].sum) != 1
        || fscanf(file, "%lf%*c", &(*ptr_s_list)[*ptr_s_items].avg) != 1
        ){    
            printf("$ !ERROR: Wrong file format to '%s'.\n", filename);
            exit(1);
        }
        (*ptr_s_items)++;
    }

score.txt内容

// txt
3 // this int num 
1   jay 100 90  80  270 90.0
2   key 90  80  65  235 78.3
3   ray 90  45  65  200 66.7
错误原因与修复方案

核心错误点

读取score[3]的fscanf判断逻辑完全错误:%d %d %d格式会尝试读取3个整数,成功时返回值为3,但你代码中判断!=1——只要读取结果不是1就触发错误,这直接导致读取分数数组时立刻触发格式错误提示。

除此之外还有几个次要问题会导致读取错位:

  • 读取name时使用%[^\n]%*c,会把当前行剩余的所有内容(包括分数、总分、平均分)全部读入name,因为%[^\n]会匹配到换行符前的所有字符,彻底打乱后续读取逻辑。
  • 循环变量s未被使用,反而依赖*ptr_s_items作为数组索引,若该变量初始值不正确,会导致数组越界或读取遗漏/重复。
  • 手动添加的%*c会干扰fscanf的空白处理:fscanf处理%d、%s、%lf等格式时会自动跳过空白字符(空格、制表符、换行),手动吃掉字符反而会导致读取错位。

修复后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TSIZE 20 // 补充原代码缺失的TSIZE定义

typedef struct {
    int no;
    char name[TSIZE];
    int score[3];
    int sum;
    double avg;
} Score;

void read_scores(FILE *file, Score **ptr_s_list, int *ptr_s_items, const char *filename) {
    int num;
    // 读取num,依赖fscanf自动跳过空白,无需手动处理换行
    if (fscanf(file, "%d", &num) != 1) {
        printf("$ !ERROR: Wrong file format to num.\n");
        exit(1);
    }

    *ptr_s_list = (Score *)malloc(sizeof(Score) * num);
    if (*ptr_s_list == NULL) {
        printf("$ !ERROR: Malloc failed.\n");
        exit(1);
    }

    *ptr_s_items = 0; // 初始化元素计数变量
    for (int s = 0; s < num; ++s) {
        // 将整行数据的读取合并为一个fscanf,判断返回值是否为7(成功读取7个字段)
        if (fscanf(file, "%d %s %d %d %d %d %lf", 
                   &(*ptr_s_list)[s].no, 
                   (*ptr_s_list)[s].name,
                   &(*ptr_s_list)[s].score[0], 
                   &(*ptr_s_list)[s].score[1], 
                   &(*ptr_s_list)[s].score[2],
                   &(*ptr_s_list)[s].sum,
                   &(*ptr_s_list)[s].avg) != 7) {    
            printf("$ !ERROR: Wrong file format to '%s'.\n", filename);
            exit(1);
        }
        (*ptr_s_items)++;
    }
}

关键修改说明

  1. 修正分数数组读取的判断逻辑:将分数数组读取的返回值判断从!=1改为整行读取的返回值等于7(或单独读取分数时判断等于3),确保只有当字段读取失败时才触发错误。
  2. 修正姓名读取方式:使用%s读取姓名,因为文件中姓名是无空格的单个字符串,%s会自动跳过前面的空白,读取到下一个空白字符为止,不会误读后续内容。
  3. 移除不必要的%*c:依赖fscanf的自动空白跳过机制,避免手动处理字符导致的读取错位。
  4. 规范循环索引使用:用循环变量s作为数组索引,同时初始化*ptr_s_items为0,避免索引错误。
  5. 补充缺失的宏定义:添加TSIZE的定义,解决原代码的编译错误。

内容的提问来源于stack exchange,提问作者user21494777

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 12:13:12