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

C语言typedef结构体数组读取文件异常求助:文件无法打开且输出全零

问题排查与代码修正方案

核心错误分析

  1. 全局作用域放置执行语句
    C语言规定,全局区域(函数外部)只能存在变量声明、宏定义、函数原型等静态代码,不能包含if代码块、函数调用这类可执行逻辑。你把文件打开和错误判断放在全局,这是导致编译失败的直接原因。

  2. 缺少必要头文件
    使用strerror()和errno需要包含<errno.h>头文件,否则会出现未定义标识符的编译错误。

  3. 数据读取逻辑错误
    GetData()函数中,首次读取name在循环外,后续循环只读取age和salary,没有读取下一条记录的name;同时循环条件判断fp是否非空无效,应该检查fscanf的返回值来确认读取是否成功。

  4. 字符串转义错误
    代码中字符串里的换行直接写了换行符,正确写法应该是用\n转义,否则会触发编译错误。

  5. 输入合法性未校验
    main()中读取用户输入的records_read时,没有判断是否超出实际读取的记录数,可能导致数组越界访问。


修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>  // 新增:用于strerror和errno
#define SIZE 10
#define ARRAY_SIZE 30

// 定义结构体
typedef struct
{
    char name[SIZE];
    int age;
    int salary;
} data;

data a[ARRAY_SIZE];  // 全局结构体数组

// 读取数据函数
int GetData(FILE *fp)
{
    int i = 0;
    // 循环读取每一条记录:name + age + salary
    while (i < ARRAY_SIZE)
    {
        // 检查是否成功读取三个字段
        int ret = fscanf(fp, "%s %d %d", a[i].name, &a[i].age, &a[i].salary);
        if (ret != 3)
        {
            // 读取失败(到文件末尾或格式错误),退出循环
            break;
        }
        i++;
    }
    return i;
}

// 打印数据函数
void ShowData(int records_read, int total_records)
{
    // 校验输入的记录数是否合法
    if (records_read < 1 || records_read > total_records)
    {
        printf("输入无效!请输入1到%d之间的数字\n", total_records);
        return;
    }
    // 打印指定数量的记录
    for (int i = 0; i < records_read; i++)
    {
        printf("%s %d %d\n", a[i].name, a[i].age, a[i].salary);
    }
}

int main()
{
    int total_records;
    int records_read;
    // 在main中打开文件(正确的执行位置)
    FILE *fp = fopen("DataFile.txt", "r");
    if (fp == NULL)
    {
        printf("打开文件失败:%s\n", strerror(errno));
        exit(1);
    }

    // 读取数据并获取总记录数
    total_records = GetData(fp);
    if (total_records == 0)
    {
        printf("未读取到任何数据\n");
        fclose(fp);
        return 0;
    }

    // 提示用户输入
    printf("请输入1到%d之间的数字:", total_records);
    scanf("%d", &records_read);

    // 打印数据
    ShowData(records_read, total_records);

    // 关闭文件
    fclose(fp);
    return 0;
}

关键修改说明

  • 将文件打开和错误判断移至main()函数内,符合C语言执行逻辑规范。
  • 新增<errno.h>头文件,解决strerror和errno的未定义问题。
  • 重构GetData()函数的读取逻辑,通过fscanf的返回值判断是否成功读取一条完整记录,确保每一条记录的name、age、salary都被正确读取。
  • 在ShowData()中新增输入合法性校验,避免数组越界。
  • 修正字符串中的换行符为\n,解决编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 06:35:17