简体   繁体   English

从文件读取到struct到终端,分段错误

[英]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)
  1. 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); 
  2. Check the result of malloc() , it returns NULL on failure. 检查malloc()的结果,它在失败时返回NULL

  3. 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) 
  4. 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_MATCHESprintf()循环,当你不必阅读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()有一个计数器但是读了下一个点。

  5. You never increment i in the while loop in read_file() . 你永远不会在read_file()中的while循环中增加i

  6. This is very weired 这非常受欢迎

     void read_file(struct match *matches); 

    do you mean 你的意思是

     read_file(matches); 
  7. 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()会导致未定义的行为,这可能是一个分段错误,或者其他任何东西,因为它是未定义的。

  8. This makes no sense 这毫无意义

     while (!fp) { ... } 

    you meant 你的意思是

     if (!fp) { ... } 
  9. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM