如何修改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; }
关键修改说明
- 结构体字段调整:将
uAd改为字符数组,支持存储多字符产品名称 - 文件指针重置:统计行数后用
rewind(f)将指针移回文件开头,确保后续能读取数据 - 过滤无效行:读取时跳过标题行,统计行数时忽略空行,只计算有效数据行
- 读取逻辑优化:用
fscanf的返回值(成功读取的参数个数)判断循环结束,避免feof的常见陷阱 - 内存安全处理:改用
malloc动态分配数组,增加内存分配失败的判断,避免栈溢出风险 - 错误处理完善:文件打开或内存分配失败时,及时终止程序并释放已占用资源
内容的提问来源于stack exchange,提问作者Mahami
相关产品推荐
相关产品推荐

