gpt4 book ai didi

c - 从文件读取结构到终端,段错误

转载 作者:太空宇宙 更新时间:2023-11-04 02:00:04 24 4
gpt4 key购买 nike

我正在尝试从具有相似行的文本文件中读取(大约 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)

最佳答案

  1. Don't转换 malloc()

    struct match *matches = (struct match *) malloc(sizeof(match) * MAX_MATCHES);

    更好的是

    struct match *matches = malloc(sizeof(struct match) * MAX_MATCHES);
  2. 检查malloc()的结果,失败返回NULL

  3. 不要检查 !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)
  4. 这是最重要的:您在 printf() 循环中迭代直到 MAX_MATCHES,当您不这样做时必须阅读 MAX_MATCHES。因此,您需要记录成功读取的项目数,并在第二个 for 循环中使用它。

    例如,您可以将读取的项目数从 read_file 返回到 main,并使用它。

    您在 read_file() 中已有一个计数器,但请阅读下一点。

  5. 您永远不会在 read_file()while 循环中递增 i

  6. 这很奇怪

    void read_file(struct match *matches);

    你是说

    read_file(matches);
  7. 这是不正确的

    free(fp);

    您已经执行了fclose(fp),这是释放FILE * 资源的正确方法,那里的free()将导致未定义的行为,这可能是段错误或其他任何事情,因为它是未定义的。

  8. 这没有意义

    while (!fp) { ... }

    你的意思是

    if (!fp) { ... }
  9. 您的read_file() 函数仅在本地分配结构,然后您无法从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()

    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;
    }

关于c - 从文件读取结构到终端,段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28442922/

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