首页 > 解决方案 > 将数据从文件保存到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呢?

标签: cstringpointersdata-structuresstruct

解决方案


您的电话有多个问题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对象,读取groupturn写入它,然后将其分配给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);
}

推荐阅读