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

如何修改C语言代码以正确读取指定格式的产品数据文件?

修复C语言文件读取代码的问题

原代码存在的核心问题

  • 统计行数后文件指针停在末尾,未重置到开头,后续读取无数据
  • 结构体中uAd定义为单个char,无法存储多字符产品名称(如CD、EFG)
  • 使用while(!feof(f))判断读取结束,会导致多执行一次循环
  • 统计行数时包含了标题行和空行,数组长度不合理
  • 文件打开失败后未终止程序,会触发后续非法操作

修改后的代码

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

// 修改结构体,用字符数组存储多字符产品名称
struct products{
    char uAd[20];  // 预留足够空间存储最长产品名
    int uSat;
    int uAl;
    int uStk;
};

int main(){
    int line = 0;
    char buffer[100];
    FILE *f = fopen("file.txt", "r");
    
    // 文件打开失败直接终止程序
    if(f == NULL) {
        perror("无法打开文件");
        return 1;
    }

    // 跳过第一行标题
    fgets(buffer, sizeof(buffer), f);
    
    // 统计有效数据行数(跳过空行)
    while(fgets(buffer, sizeof(buffer), f) != NULL){
        if(buffer[0] != '\n' && buffer[0] != '\r'){
            line++;
        }
    }

    // 将文件指针重置到开头,再次跳过标题行
    rewind(f);
    fgets(buffer, sizeof(buffer), f);

    // 动态分配内存存储数据,比变长数组更安全
    struct products *U = malloc(line * sizeof(struct products));
    if(U == NULL){
        perror("内存分配失败");
        fclose(f);
        return 1;
    }

    int i = 0;
    // 用fscanf返回值判断是否成功读取一组数据,避免feof陷阱
    while(fscanf(f, "%s %d %d %d", U[i].uAd, &U[i].uSat, &U[i].uAl, &U[i].uStk) == 4){
        i++;
    }

    // 输出所有读取到的有效数据
    for(int j=0; j<line; j++) {
        printf("%-10s %-5d %-5d %-5d\n", U[j].uAd, U[j].uSat, U[j].uAl, U[j].uStk);
    }

    // 释放资源
    free(U);
    fclose(f);

    return 0;
}

关键修改说明

  1. 结构体字段调整:将uAd改为字符数组,支持存储多字符产品名称
  2. 文件指针重置:统计行数后用rewind(f)将指针移回文件开头,确保后续能读取数据
  3. 过滤无效行:读取时跳过标题行,统计行数时忽略空行,只计算有效数据行
  4. 读取逻辑优化:用fscanf的返回值(成功读取的参数个数)判断循环结束,避免feof的常见陷阱
  5. 内存安全处理:改用malloc动态分配数组,增加内存分配失败的判断,避免栈溢出风险
  6. 错误处理完善:文件打开或内存分配失败时,及时终止程序并释放已占用资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 07:55:31