编程新手求教:如何将文件数据映射至C语言数据结构?
如何将文件数据读取到C语言结构体中
嘿,作为编程新手能尝试自己写代码已经很棒啦!我来帮你梳理一下怎么实现把文件里的姓名、地址、序列号、职务数据赋值给结构体,先看看你代码里的几个小问题,再给你完整的解决方案~
你现有代码里的几个问题
- 结构体定义缺少需求里的姓名字段,你需要存储姓名,但当前
pers结构体只有年龄、地址、序列号、职务,得补上姓名项 while(!feof(f1))的用法有坑:feof只有在读取到文件末尾之后才会返回真,这会导致最后一次循环多读一次无效数据,正确的做法是用读取函数的返回值来判断循环是否继续fread(&a1, sizeof(f1),1,f1)==num_tot[21]完全错误:sizeof(f1)是文件指针的大小(通常8字节),不是int的大小;而且num_tot是长度为21的字符串,num_tot[21]已经超出数组下标范围(数组索引从0到20),这个判断逻辑不成立- 注释掉的
pers p[n];是变长数组,虽然C99支持,但如果n是运行时确定的,最好先读取人数再分配内存,或者用动态内存分配(malloc)
正确实现方案
首先明确你的文件bd.txt的存储格式,通常文本文件会按行或者固定格式存储每条记录,比如每条记录格式可能是:
张三 北京市朝阳区 10001 工程师 李四 上海市浦东新区 10002 设计师
下面分文本文件读取和二进制文件读取两种情况给出示例:
情况1:文本文件读取(最常见)
#include<stdio.h> #include<stdlib.h> // 修正结构体,加上姓名字段,和需求匹配 typedef struct { char name[50]; // 姓名 char address[50]; // 地址 long serial_num; // 序列号 char function[25];// 职务 } Person; int main() { FILE *f1; int count = 0; Person *people; // 用指针动态分配内存 // 打开文件,只读模式 f1 = fopen("bd.txt", "r"); if (f1 == NULL) { perror("无法打开文件"); return 1; } // 先统计文件里的记录数量(假设每条记录占一行) char temp[200]; while (fgets(temp, sizeof(temp), f1) != NULL) { count++; } // 回到文件开头 rewind(f1); // 动态分配内存存储所有人员数据 people = (Person*)malloc(count * sizeof(Person)); if (people == NULL) { perror("内存分配失败"); fclose(f1); return 1; } // 读取每条记录到结构体数组 int i; for (i = 0; i < count; i++) { // 按照文本格式读取,注意格式符要和文件内容匹配 fscanf(f1, "%s %s %ld %s", people[i].name, people[i].address, &people[i].serial_num, people[i].function); } // 测试输出,验证读取是否成功 printf("读取到%d条记录:\n", count); for (i = 0; i < count; i++) { printf("姓名:%s,地址:%s,序列号:%ld,职务:%s\n", people[i].name, people[i].address, people[i].serial_num, people[i].function); } // 释放内存和关闭文件 free(people); fclose(f1); return 0; }
情况2:二进制文件读取(如果文件是二进制存储)
如果你的bd.txt实际是二进制文件(比如之前用fwrite写入的结构体数据),可以用fread直接读取:
#include<stdio.h> #include<stdlib.h> typedef struct { char name[50]; char address[50]; long serial_num; char function[25]; } Person; int main() { FILE *f1; int count = 0; Person *people; Person temp_person; f1 = fopen("bd.txt", "rb"); // 二进制只读模式 if (f1 == NULL) { perror("无法打开文件"); return 1; } // 统计记录数量:总文件大小 / 单个结构体大小 fseek(f1, 0, SEEK_END); long file_size = ftell(f1); count = file_size / sizeof(Person); rewind(f1); people = (Person*)malloc(count * sizeof(Person)); if (people == NULL) { perror("内存分配失败"); fclose(f1); return 1; } // 一次性读取所有数据,或者循环读取 fread(people, sizeof(Person), count, f1); // 测试输出 printf("读取到%d条记录:\n", count); for (int i = 0; i < count; i++) { printf("姓名:%s,地址:%s,序列号:%ld,职务:%s\n", people[i].name, people[i].address, people[i].serial_num, people[i].function); } free(people); fclose(f1); return 0; }
关键注意事项
- 结构体的字段要和文件里的数据顺序、类型完全匹配,否则会读取错误
- 操作文件后一定要记得
fclose,避免资源泄漏 - 动态分配的内存要用
free释放,防止内存泄漏 - 如果文本文件里的地址包含空格(比如“北京市 朝阳区”),
%s无法读取完整,这时候需要用fgets读取整行,再手动分割字符串
内容的提问来源于stack exchange,提问作者STARK
相关产品推荐
相关产品推荐

