[英]Reading from file to struct into terminal, segmentation fault
I'm trying to read from a text file with similar lines (about 200 of them with some empty lines now and then). 我正在尝试从具有类似线条的文本文件中读取(其中大约200个,其中有一些空行)。 I know that something can be uninitialized, but I'm blank as to what it is. 我知道某些东西可能是未初始化的,但我对它是什么一无所知。 What I'm trying to do right now is just read from a file and print it into the terminal window. 我现在正在尝试做的只是从文件中读取并将其打印到终端窗口中。
I really hope you can help me! 我真的希望你能帮助我! Thank you. 谢谢。
Example of a few lines of text file: 几行文本文件的示例:
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
My struct looks like this: 我的结构看起来像这样:
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;
};
My read_file
function looks like this: 我的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);
}
And my main
function looks like this: 我的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;
}
It compiles with no problems, but I get a Segmentation fault
when I try to run it. 它没有任何问题编译,但是当我尝试运行它时,我遇到了Segmentation fault
。 I then use Valgrind, and it gives me this message: 然后我使用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)
Don't cast malloc()
不要投射malloc()
struct match *matches = (struct match *) malloc(sizeof(match) * MAX_MATCHES);
is better as 更好的
struct match *matches = malloc(sizeof(struct match) * MAX_MATCHES);
Check the result of malloc()
, it returns NULL
on failure. 检查malloc()
的结果,它在失败时返回NULL
。
Don't check !feof()
because it's always wrong , so change this 不要检查!feof()
因为它总是错误的 ,所以改变它
while(!feof(fp))
with 同
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)
And this is the most important : you iterate until MAX_MATCHES
in the printf()
loop, when you don't necessarily have read MAX_MATCHES
. 这是最重要的 :你迭代,直到MAX_MATCHES
在printf()
循环,当你不必阅读MAX_MATCHES
。 So you need to keep a count of the successfuly read items, and use that in the second for
loop. 因此,您需要保留成功读取项目的计数,并在第二个for
循环中使用它。
You can for example return the count of read items from read_file
to main, and use it. 例如,您可以将读取项的计数从read_file
到main,然后使用它。
You already have a counter in read_file()
but read the next point. 你已经在read_file()
有一个计数器但是读了下一个点。
You never increment i
in the while
loop in read_file()
. 你永远不会在read_file()
中的while
循环中增加i
。
This is very weired 这非常受欢迎
void read_file(struct match *matches);
do you mean 你的意思是
read_file(matches);
This is incorrect 这是不正确的
free(fp);
you already did fclose(fp)
which is the correct way to release a FILE *
's resources, the free()
there will cause undefined behavior, which could be a segmentation fault, or any thing else, since it's undefined. 你已经做了fclose(fp)
这是释放FILE *
资源的正确方法, free()
会导致未定义的行为,这可能是一个分段错误,或者其他任何东西,因为它是未定义的。
This makes no sense 这毫无意义
while (!fp) { ... }
you meant 你的意思是
if (!fp) { ... }
Your read_file()
function only localy allocates the structs
and then you have no access to them from main()
, what you can do is this 你的read_file()
函数只有localy分配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; }
and then your main()
然后你的main()
int main(int argc, char *argv[]) { int i; struct match *matches; int count; count = read_file(&matches); for (i = 0 ; i < MAX_count ; ++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); } free(matches); return 0; }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.