2015-02-10 31 views
1

我想从具有类似行的文本文件中读取(其中大约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

http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong – 2015-02-10 22:17:35

+0

确定MAX_MATCHES是足够大的为您的文件? – m0skit0 2015-02-10 22:21:48

回答

3
  1. Don'tmalloc()

    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. 您永远不会在循环中增加iread_file()

  6. 这是非常weired

    void read_file(struct match *matches); 
    

    你的意思

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

    free(fp); 
    

    你已经做了fclose(fp)这是正确的方式来释放FILE *的资源,free()会导致未定义的行为,这可能是分段错误或其他任何事情,因为它是未定义的。

  8. 这是没有意义的

    while (!fp) { ... } 
    

    你的意思

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

    然后你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; 
    } 
    
+0

非常感谢您的回答!我没有期待这么彻底的答案,我很感激!如果我能鼓励你,我会,但我还没有9的声望。 谢谢! – jmkjaer 2015-02-11 00:50:40