如何解决在检查新行的同时使用 fscanf 从文件中填充结构数组反馈
id name surname 78 99 101 12 33 44
每一行我都需要填充一个 Student
结构体。 surname
之后的数字必须存储在结构体数组 Lesson
中。第一个数字(例如 78
)是一个结构体字段,第二个数字(99
)是另一个结构体字段。姓氏后面的对最多可以是 8。我有点困惑,因为我不知道会有多少对,我找到了这个方法,但不确定我检查换行符 (\n) 的方式是否好。
typedef struct Lesson
{
int hour;
int time;
}Lesson;
typedef struct Student
{
int id;
char name_and_surname[100];
Lesson lessons[8];
struct Student *next;
}Student;
Student s;
while (fscanf(fp,"%d %s %s",&s.id,s.name_and_surname,tmp) == 3)
{
int i = 0;
strcat(s.name_and_surname," ");
strcat(s.name_and_surname,tmp);
while ((ch = fgetc(fp) != '\n') && fscanf(fp,"%d %d",&s.lessons[i].hour,&s.lessons[i].time) == 2)
{
i++;
}
//add s to a linked list
}
解决方法
正如我在评论中所说的那样,如果您的输入被组织为每行一条记录并带有可变格式行,那么最好一次读取整行,也许使用 fgets()
,然后将结果解析为其字段。解析有许多替代方案,其中包括 sscanf()
、strtok()
和 strtol()
。
如果您必须通过fscanf()
直接扫描每个字段来完成这项工作,那么这是可能的,但很麻烦。您提出的特定方法并不可靠:它不会识别带有尾随空格的行上的换行符,也不会识别因尾随数字为奇数而格式错误的行。
例如,您可以改用以下内容:
/*
* Scan one int from file 'fp' into the location pointed to by 'dest',* skipping any leading whitespace other than newlines.
*
* Returns:
* 1 on success
* 0 if a non-numeric field is found before the next newline
* EOF if end of file or end of line is reached without encountering
* an input field,or on error
*/
int scan_one_number(FILE *fp,int *dest) {
// skip leading whitespace,but stop at a newline
while (1) {
int c = fgetc(fp);
if (c == EOF || c == '\n') {
// terminate on error,end-of-file,or end-of-line
return EOF;
} else if (!isspace(c)) {
// a non-whitespace character
// push it back onto the stream
if (ungetc(c,fp) != c) {
// error
return EOF;
}
// break out of the loop
break;
} // else it's non-newline whitespace; ignore it
}
// attempt to scan a decimal integer
return fscanf(fp,"%d",dest);
}
这将允许您使用 scanf
一次扫描一个数字,识别行尾和格式错误的输入。
我觉得只要你知道Lesson的输入必须是成对的并且不会奇数就可以了。 在这种情况下,您可以用 0 或 null 甚至 -1 左右填充数组课程的末尾。你这样做是因为你可能想在之后打印它。 类似的东西:
for (j = 0; j < i; j++)
{
s.lessons[j].hour = 0;
s.lessons[j].time = 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。