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

如何在C语言中用fscanf将文件内容读取到结构体?读取失败求助

无法将文件中学生信息存入结构体的问题分析与修复

你的代码存在多个关键问题,导致无法正确读取文件内容到结构体,以下是具体问题和修复方案:

核心问题点

  • 函数声明不匹配:开头的readStudentsFromFile();等声明未指定参数和返回类型,与后续定义冲突,会引发编译错误。
  • 结构体字段错误:struct Student中的grade被定义为int grade[100];,但每个学生仅对应一个成绩,应改为int grade;。
  • 文件读取逻辑错误:
    1. 统计行数时,while(!feof(file))配合fgetc会导致行数多算一次(feof需读取到文件末尾后才会触发),且读完后文件指针停在末尾,后续fscanf无法读取内容。
    2. fscanf参数错误:name、surname、number是字符数组名,本身就是指针,无需加&;若grade是单个int,需传递&var[i].grade。
  • 局部变量作用域问题:readStudentsFromFile中定义的struct Student var[100]是局部变量,函数执行完毕后会被销毁,主函数中的var数组未被赋值,自然无法正确显示内容。
  • 不安全的输入函数:gets(fileName)存在缓冲区溢出风险,应使用fgets替代。
  • count初始化错误:初始值设为1会导致空文件时行数统计错误,应从0开始。

修复后的代码

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

// 修正结构体,grade改为单个int
struct Student {
    char name[100], surname[100], number[100];
    int grade;
};

// 正确声明函数,指定参数和返回类型
void readStudentsFromFile(struct Student students[], int *count);

int main() {
    struct Student var[100];
    int studentCount;
    readStudentsFromFile(var, &studentCount);

    // 测试打印读取到的学生信息
    for(int i = 0; i < studentCount; i++){
        printf("学生%d: %s %s, 学号:%s, 成绩:%d\n", 
               i+1, var[i].name, var[i].surname, var[i].number, var[i].grade);
    }
    return 0;
}

void readStudentsFromFile(struct Student students[], int *count) {
    char fileName[100];
    printf("Enter file name: ");
    // 用fgets替代gets,处理换行符
    fgets(fileName, sizeof(fileName), stdin);
    fileName[strcspn(fileName, "\n")] = '\0'; // 去掉fgets读取的换行符

    FILE *file = fopen(fileName, "r");
    if (!file) {
        printf("Error: Unable to open file %s\n", fileName);
        *count = 0;
        return;
    }

    int i = 0;
    // 直接用fscanf读取,直到文件末尾,无需先统计行数
    while (fscanf(file, "%s %s %s %d", 
                  students[i].name, students[i].surname, students[i].number, 
                  &students[i].grade) == 4) {
        i++;
    }
    *count = i;

    fclose(file);
}

修复说明

  1. 将结构体的grade改为单个int,匹配每个学生一个成绩的需求。
  2. 把主函数中的结构体数组传递给readStudentsFromFile,直接在该数组中写入数据,避免局部变量销毁导致的数据丢失。
  3. 移除先统计行数的冗余逻辑,直接通过fscanf的返回值判断读取是否成功,简化代码同时避免文件指针位置问题。
  4. 用fgets替代gets,提升输入安全性,并处理换行符。
  5. 正确声明函数,指定返回类型和参数,消除编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 13:24:58