将数据从文件保存到c中的结构
Posted
技术标签:
【中文标题】将数据从文件保存到c中的结构【英文标题】:Saving data from a file to a struct in c 【发布时间】:2021-11-20 23:15:23 【问题描述】:我有两个必须用学生数据填充的结构。数据格式为:
年龄、姓名、年级、年龄、组别、轮次
文件头中是数据中的学生人数。
struct school //school
char group; //A,B,C,D,E,F
char turn; //Morning, AFTERNOON
;
struct student
char *name;
char *grade;
int age;
struct school *E;
student[6];
我尝试先从只有年龄、姓名和年级的文本中保存数据,看看我是否可以做到:
void get_file(const char* file, int *n) //n is the amount of students
FILE* fptr;
fptr = fopen(file, "r");
if (fptr == NULL)
printf( "\n Error \n");
exit(1);
char* temp;
int tam = 0;
fscanf(fptr, "%d", n); //size of the list of students
for(int i= 0; i < *n; i++)
fscanf(fptr, "%d,%s,%s", &student.age[i],temp, student[i].grade);
tam = strlen(temp);
student[i].name = (char*)malloc(tam * sizeof(char));
strcpy(student[i].name, temp);
printf("%s\n", student[i].name);//to see if it's correct the content
fclose(fptr);
但是,student.name
存储例如 "Josh, A+"
,而它应该只是 "Josh"
。我该如何解决这个问题?
这是一个任务。
编辑: 我的数据是这样的
4 //size of list
Josh,A,20,D,M
Amber,B,23,E,M
Kevin,C,22,D,A
Adam,A+,21,C,A
使用 Remy Lebeau 的解决方案,我得到了这个
void get_file(const char* file, int *n)
*n = 0;
FILE* fptr = fopen(file, "r");
if (fptr == NULL)
printf( "\n Error \n");
exit(1);
char name[80];
char grade[2];
fscanf(fptr, "%d", n); //size of the list of students
for(int i = 0; i < *n; i++)
fscanf(fptr, "%80[^,],%2[^,],%d,%c,%c", &student[i].age, name, grade,&student[i].group, &student[i].turn);
student[i].name = strdup(name);
student[i].grade = strdup(grade);
fclose(fptr);
但是我遇到了问题,因为我做了这个改变
struct student
char *name;
char *grade;
int age;
struct school E; //it was struct school *E
student[6];
要传递信息,但是老师说我不能改,那我怎么加载struct school *E
的信息呢?
【问题讨论】:
发布答案后,请不要通过应用答案中建议的更正来更改您的问题,因为这会使答案无效。 将数据从文件移动到内存中通常称为加载,而不是保存。 【参考方案1】:您致电fscanf()
存在多个问题:
&student.age[i]
必须是 &student[i].age
。
temp
和student::grade
是未初始化的指针,它们不指向任何地方,因此将数据读取到它们指向的内存是未定义的行为。 fscanf()
不会为你分配内存,你需要自己为fscanf()
预先分配char[]
缓冲区,然后才能读入。
%s
读取非空白字符包括 ','
,这就是为什么您的代码不会在Josh
之后的,
上停止。尝试在该字段中使用 %[^,]
而不是 %s
。
试试这样的:
void get_file(const char* file, int *n)
*n = 0;
FILE* fptr = fopen(file, "r");
if (fptr == NULL)
printf( "\n Error \n");
exit(1);
char name[256];
char grade[5];
fscanf(fptr, "%d", n); //size of the list of students
for(int i = 0; i < *n; i++)
fscanf(fptr, "%d,%255[^,],%4s", &student[i].age, name, grade);
student[i].name = strdup(name);
student[i].grade = strdup(grade);
printf("%d %s %s\n", student[i].age, student[i].name, student[i].grade);
fclose(fptr);
更新:
您现在显示的文件数据与您描述的格式不匹配,这是您的代码所期望的。您将文件数据描述(并编码)为:
age, name, grade, age, group, turn
(为什么是 2 个年龄?)
但你显示的更像:
name, grade, age, group, turn
您将fscanf()
中的格式字符串更改为这种新格式,但您没有更改读取变量的顺序以匹配此格式。因此,您将name
值读入age
字段,将grade
值读入name
字段,并将age
值读入grade
字段。
此外,您甚至没有尝试正确处理 group
和 turn
。它们位于完全不同的结构中,您没有为其分配任何内存。您需要分配一个school
对象,将group
和turn
读入其中,然后将其分配给student[i].E
。
话虽如此,请尝试更多类似的东西:
struct school
char group; //A,B,C,D,E,F
char turn; //Morning, AFTERNOON
school[6];
struct student
char *name;
char *grade;
int age;
struct school *E;
student[6];
void get_file(const char* file, int *n)
*n = 0;
FILE* fptr = fopen(file, "r");
if (fptr == NULL)
printf( "\n Error \n");
exit(1);
char name[81];
char grade[3];
fscanf(fptr, "%d", n); //size of the list of students
for(int i = 0; i < *n; i++)
student[i].E = &school[i]; // or, use malloc() instead, if needed...
fscanf(fptr, " %80[^,],%2[^,],%d,%c,%c", name, grade, &(student[i].age), &(student[i].E->group), &(student[i].E->turn));
student[i].name = strdup(name);
student[i].grade = strdup(grade);
fclose(fptr);
【讨论】:
我试过了,它只打印列表中的第一个名字 一个问题是您的代码没有尝试读取文件中的所有数据。只读取了第一个学生的一部分数据后,留下了更多数据。因此,当您的循环尝试读取第二个学生时,它实际上是从第一个学生那里读取剩余的数据。如果你不打算读取一个学生的所有数据,我建议你使用getline()
或类似的函数一次读取整个学生,然后你可以使用sscanf()
解析出你需要的值。
我对@987654354@ 做了同样的事情:我创建了另一个变量,比如temp
来存储
好点,我错过了。我已经更新了我的答案以说明这一点。无论如何,当您没有显示文件数据的实际外观时,很难诊断您的问题。不要描述数据,显示数据。
我想将所有数据存储在文件中,我制作的函数是一种有效的方法吗?我没有其他想法将信息存储在指针```名称```中以上是关于将数据从文件保存到c中的结构的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据结构中的字段保存到 Matlab 中的文件名字段?