我发现了在struct 中存储学生成绩的最佳方式。一般来说,每个学生都有名字、姓氏、成绩……你可以添加任何你想要的东西。我对fname、lname、grades 很好。
typedef struct student_s {
char fname[25];
char lname[25];
int* grades;
int count_of_grades; // Track number of grades for each student
} student_t;
通过分配student_t 的动态数组,您可以获得尽可能多的学生。
// Allocate array of structs
student_t* students = (student_t *) malloc(sizeof(student_t));
通过使用getline(),您可以一次从文件中读取整行(行以\n 结尾)。 getline() 不是标准的 C 函数,因此您需要将 #define _GNU_SOURCE 放在脚本的开头。
while ((read_len = getline(&line, &len, fp)) != -1)
函数getline()每次读取文件的下一行,数组大小count将递增并重新分配数组。
++count;
// Increase size of array beacause of new student to add
students = realloc(students, sizeof(student_t) * count);
if (students == NULL)
{
printf("Couldn't allocated memmory\n");
return 1;
}
下一步是分配grades 数组,该数组将存储特定学生的所有成绩。循环通过line,您可以提取每个等级。然后只需定义 struct 的成员,您就可以为每个学生添加成绩。
// Allocate array to store all grades from file for one student
// Count of grades does not have to be the same for every student
students[index].grades = (int *) malloc(sizeof(int) * (read_len-1));
// Iterate grades read from file
for (int i=0; i<read_len-1; ++i)
{
// char --> char *
char grade[2] = "\0";
grade[0] = line[i];
// Add grade to the array of grades
students[index].grades[i] = atoi(grade);
}
最后,您应该将成绩数存储在数组中,以便稍后在脚本中对数据进行简单操作。
// Track number of grades
students[index].count_of_grades = read_len-1;
++index
完整代码:
#define _GNU_SOURCE // necessery to use getline()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct student_s {
char fname[25];
char lname[25];
int* grades;
int count_of_grades;
} student_t;
int main(int argc, char const *argv[])
{
// Allocate array of structs
student_t* students = (student_t *) malloc(sizeof(student_t));
int count = 0;
int index = 0;
FILE* fp;
char* line = NULL;
size_t len = 0;
ssize_t read_len;
fp = fopen("data.txt", "r");
if (fp == NULL)
{
return 1;
}
// Read line by line from file until fp reaches end of file
while ((read_len = getline(&line, &len, fp)) != -1)
{
++count;
// Increase size of array beacause of new student to add
students = realloc(students, sizeof(student_t) * count);
if (students == NULL)
{
printf("Couldn't allocated memmory\n");
return 1;
}
// Replace with your code, which adds name to struct or get rid of it (also from struct)
memcpy(students[index].fname, "John", 4);
memcpy(students[index].lname, "Wash", 4);
// Allocate array to store all grades from file for one student
// Count of grades does not have to be the same for every student
students[index].grades = (int *) malloc(sizeof(int) * (read_len-1));
// Iterate grades read from file
for (int i=0; i<read_len-1; ++i)
{
// char --> char *
char grade[2] = "\0";
grade[0] = line[i];
// Add grade to the array of grades
students[index].grades[i] = atoi(grade);
}
// Track number of grades
students[index].count_of_grades = read_len-1;
++index;
}
fclose(fp);
if (line)
{
free(line);
}
// Print data from structs
for (int i=0; i<count; ++i)
{
printf("%s: ", students[i].fname);
for (int j=0; j<students[i].count_of_grades; ++j)
{
printf("%d ", students[i].grades[j]);
}
printf("\n");
}
return 0;
}