gpt4 book ai didi

c - 将数据从文件读取到结构中时遇到问题

转载 作者:行者123 更新时间:2023-11-30 17:30:15 26 4
gpt4 key购买 nike

我需要一些代码方面的帮助。我有一个文本文件,如下所示:

131782 Mathematics 59
075160 Mathematics 92
580313 Physics 63
073241 Mathematics 32
487476 Mathematics 73
075160 Physics 98
472832 English 44
...

其中有 80 行数据,对应于 20 个学生、4 个不同的科目以及他们在该科目上获得的分数。我想以这样的方式排列数据(学生证旁边有四个标记):

第一个表:

868717 2 37 49 15
472832 44 88 91 95
580313 91 97 63 78
...

所以会有二十行数据。然后用另一个表来查找每个学生分数的平均值,并查找另一个科目中每个科目的平均值。现在我对此没有问题,我遇到的问题是将数据放入结构中。如果您查看我的代码,我会以字符串形式读取数据并将其存储在 char 的字符串数组中。我仍然使用 malloc() 来动态分配,但完成后我会这样做。我想在数组中搜索学生 ID 并使用 update_student() 函数填充他们的分数,但我在如何将包含数据的字符串读入函数中时遇到了麻烦,因为有三个每个字符串的部分、学生 ID 主题和分数。如果您查看我的代码末尾,这就是我所能得到的。我计划设置一个 for 循环以将数据传入 update_student() 函数,但似乎无法设置代码。

有人有任何想法可以将此数据放入我的结构中吗?

#include <stdio.h>
#include <string.h>

#define STUDENTS (20)
#define NOBODY_ID (-1)
#define EMPTY_MARK (-1)
#define NO_STUDENT (-1)

#define SUBJECT_ENGLISH (0)
#define SUBJECT_MATHEMATICS (1)
#define SUBJECT_PHYSICS (2)
#define SUBJECTS (3)

#define STRING_LENGTH 23
#define NUMBER_OF_LINES 80

struct student
{
int id;
int marks[SUBJECTS];
}; struct student db[STUDENTS];

void init_db()
{
int i, j;
for( i = 0; i < STUDENTS; ++i )
{
db[i].id = NOBODY_ID;
for( j = 0; j < SUBJECTS; ++j )
{
db[i].marks[j] = EMPTY_MARK;
}
}
}

int find_student(const int id)
{
int i;
for( i = 0; i < STUDENTS; ++i )
{
if( db[i].id == id )
{
return i;
}
}
return NO_STUDENT;
}

void update_student(const int id, const int subject, const int mark)
{
int idx = find_student(id);
if( idx == NO_STUDENT )
{
idx = find_student(NOBODY_ID);
db[idx].id = id;
}

db[idx].marks[subject] = mark;
}

int main(void)
{
FILE *input_file;

int i=0;
char buffer[STRING_LENGTH];
char strings[NUMBER_OF_LINES][STRING_LENGTH];

if((input_file=fopen("C:\\marks\\marks.txt", "r"))==NULL)
perror("File open failed!");
else
{
while(fgets(buffer, STRING_LENGTH, input_file)!=NULL)
{
strcpy(strings[i], buffer);
i++;
}
}

for() /*Here is where I need help with*/
update_student();

return 0;
}

最佳答案

首先,对您的代码进行一些评论。

您谈论了 4 个不同的主题,但您的代码只有 3 个:#define SUBJECTS (3)

在这种情况下,为什么不使用枚举而不是定义?

enum Subject { ENGLISH, MATHEMATICS, PHYSICS };

您可能想坚持一种命名约定:

#define STUDENTS (20)
#define SUBJECTS (3)
#define NUMBER_OF_LINES 80 // I think we all know this is a number

如果你做得足够好,你可以安全地默认初始化你的学生“数据库”,并在迭代数组时用正确的值写入所有内容。通过这样做,您可以删除 NOBODY_ID 和 NO_STUDENT。但是,您可能希望保留 EMPTY_MARK,以防没有相应的标记(但如果实际上有 80 行不同的数据,则不应发生这种情况)。如果学生 ID 少于 20 个,您可能还想保留 NOBODY_ID(也可以将其重命名为“EMPTY_ID”)。

此外,当您打开文件时,最好像以前一样检查错误,但如果确实发生错误,您通常希望退出程序。

// Your code
if((input_file=fopen("C:\\marks\\marks.txt", "r"))==NULL)
perror("File open failed!");
else // You don't need this, just exit !
{
// ...
}

// Exiting when catching an error
input_file = fopen("C:\\marks\\marks.txt", "r");
if (input_file == NULL) {
perror("File open failed!");
return -1;
}
// ...

顺便说一句,我认为 Windows 接受文件路径中的斜杠:"C:/marks/marks.txt"

现在关于您的问题。

首先,您需要一种方法来识别与主题相对应的字符串(例如“Physics”)。您可以简单地使用诸如 const char*
之类的东西然后,您希望能够将一串数字转换为一个数字,可能作为一个独立的函数(提示:只需为每个新数字乘以 10)。
最后,你必须隔离每一行的每一条数据。在您的情况下,似乎空格(或换行符)分隔了两条数据。

如果你想知道某个字符的类别,ctype.h中有一些函数。 ;例如,如果您逐个字符地读取文件,则可以使用 isspace 来方便地处理似乎分隔数据 block (包括换行符)的所有内容。您还可以使用 isalpha 和 isdigit 来验证输入,也可以使用 tolower 或 toupper 来比较字符串。但是,如果您只想检测空格,则只需 == ' ' 即可。

另一种方法是使用 the scanf family 的函数(fscanf、sscanf...)。但只有当您确定所读取的数据(输入格式)时才使用它。

关于c - 将数据从文件读取到结构中时遇到问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25218710/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com