2015-02-10 26 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