我正在尝试从具有类似线条的文本文件中读取(其中大约200个,其中有一些空行)。 我知道某些东西可能是未初始化的,但我对它是什么一无所知。我现在要做的就是从文件中读取并将其打印到终端窗口。
我真的希望你能帮助我! 谢谢。
几行文本文件的示例:
Fre 19/07 18.30 AGF - FCM 0 - 2 9.364
Lor 20/07 17.00 VFF - RFC 2 - 2 4.771
Son 21/07 14.00 OB - SDR 1 - 1 7.114
我的结构看起来像这样:
struct match {
char weekday[MAX_NAME_LEN];
int day;
int month;
int hours;
int minutes;
char home_team[MAX_NAME_LEN];
char away_team[MAX_NAME_LEN];
int home_team_goals;
int away_team_goals;
int spectators_thds;
int spectators_hdrs;
};
我的read_file
函数如下所示:
void read_file(struct match *match) {
FILE *fp;
int i;
fp = fopen("superliga-2013-2014", "r");
while (!fp) {
error("Cannot open file.");
}
struct match *matches = (struct match *) malloc(sizeof(match) * MAX_MATCHES);
while(!feof(fp)) {
fscanf(fp, " %s %i/%i %i.%i %s - %s %i - %i %i.%i \n",
matches[i].weekday, &matches[i].day, &matches[i].month, &matches[i].hours,
&matches[i].minutes, matches[i].home_team, matches[i].away_team,
&matches[i].home_team_goals, &matches[i].away_team_goals,
&matches[i].spectators_thds, &matches[i].spectators_hdrs);
}
fclose(fp);
free(fp);
}
我的main
函数看起来像这样:
int main(int argc, char *argv[]) {
int i;
struct match *matches;
void read_file(struct match *matches);
for (i = 0; i < MAX_MATCHES; ++i) {
printf(" %s %i/%i %i.%i %s - %s %i - %i %i.%i ",
matches[i].weekday, matches[i].day, matches[i].month, matches[i].hours,
matches[i].minutes, matches[i].home_team, matches[i].away_team,
matches[i].home_team_goals, matches[i].away_team_goals,
matches[i].spectators_thds, matches[i].spectators_hdrs);
}
return 0;
}
它编译时没有问题,但是当我尝试运行它时,我得到Segmentation fault
。然后我使用Valgrind,它给了我这个信息:
==12799== Use of uninitialised value of size 8
==12799== at 0x4007B8: main (in /home/dradee/Dropbox/UNI/Programmering/C/readfile)
==12799==
==12799== Invalid read of size 4
==12799== at 0x4007B8: main (in /home/dradee/Dropbox/UNI/Programmering/C/readfile)
==12799== Address 0x34 is not stack'd, malloc'd or (recently) free'd
==12799==
==12799==
==12799== Process terminating with default action of signal 11 (SIGSEGV)
==12799== Access not within mapped region at address 0x34
==12799== at 0x4007B8: main (in /home/dradee/Dropbox/UNI/Programmering/C/readfile)
答案 0 :(得分:3)
Don't施放malloc()
struct match *matches = (struct match *) malloc(sizeof(match) * MAX_MATCHES);
更好
struct match *matches = malloc(sizeof(struct match) * MAX_MATCHES);
检查malloc()
的结果,失败时返回NULL
。
不要检查!feof()
,因为它是always wrong,所以请更改此
while(!feof(fp))
与
while (fscanf(fp, " %s %i/%i %i.%i %s - %s %i - %i %i.%i \n",
matches[i].weekday, &matches[i].day, &matches[i].month, &matches[i].hours,
&matches[i].minutes, matches[i].home_team, matches[i].away_team,
&matches[i].home_team_goals, &matches[i].away_team_goals,
&matches[i].spectators_thds, &matches[i].spectators_hdrs) == 11)
这是重要:您在MAX_MATCHES
循环中迭代到printf()
,当您不一定阅读MAX_MATCHES
时。因此,您需要保留成功读取项目的计数,并在第二个for
循环中使用它。
例如,您可以将读取项目的数量从read_file
返回到main,并使用它。
您已在read_file()
中设置了一个计数器,但请阅读下一点。
您永远不会在i
的{{1}}循环中增加while
。
这是非常受欢迎的
read_file()
你是说吗?
void read_file(struct match *matches);
这是不正确的
read_file(matches);
你已经free(fp);
这是发布fclose(fp)
资源的正确方法,FILE *
会导致未定义的行为,可能是分段错误,或任何事情否则,因为它未定义。
这没有任何意义
free()
你的意思
while (!fp) { ... }
您的if (!fp) { ... }
函数只有localy会分配read_file()
,然后您无法从structs
访问它们,您可以做的就是这个
main()
然后是您的int read_file(struct match **matches)
{
FILE *fp;
int i;
struct match *match;
if (matches == NULL)
return 0;
*matches = NULL;
fp = fopen("superliga-2013-2014", "r");
if (!fp)
{
error("Cannot open file.");
return 0;
}
match = malloc(sizeof(struct match) * MAX_MATCHES);
if (match == NULL)
return 0;
while ((fscanf(fp, " %s %i/%i %i.%i %s - %s %i - %i %i.%i \n",
match[i].weekday, &match[i].day, &match[i].month, &match[i].hours,
&match[i].minutes, match[i].home_team, match[i].away_team,
&match[i].home_team_goals, &match[i].away_team_goals,
&match[i].spectators_thds, &match[i].spectators_hdrs) == 11) && (i < MAX_MATCHES))
{
i++;
}
fclose(fp);
*matches = match;
return i;
}
main()