将文件中的数据保存到c中的结构
Saving data from a file to a struct in c
我有两个结构必须用学生数据填充。数据格式为:
年龄、姓名、年级、年龄、组、转
文件头是数据中的学生人数。
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
怎么加载资料?
您对 fscanf()
的调用存在多个问题:
&student.age[i]
需要 &student[i].age
.
temp
和student::grade
是未初始化的指针,它们不指向任何地方,所以读取数据到它们指向的内存是未定义的行为。 fscanf()
不会为你分配内存,你需要自己预先分配 char[]
缓冲区供 fscanf()
读取。
%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);
}
我有两个结构必须用学生数据填充。数据格式为:
年龄、姓名、年级、年龄、组、转
文件头是数据中的学生人数。
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
怎么加载资料?
您对 fscanf()
的调用存在多个问题:
&student.age[i]
需要&student[i].age
.temp
和student::grade
是未初始化的指针,它们不指向任何地方,所以读取数据到它们指向的内存是未定义的行为。fscanf()
不会为你分配内存,你需要自己预先分配char[]
缓冲区供fscanf()
读取。%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);
}