2017-01-22 120 views
2

我想從列表中讀取行到我的結構,它幾乎工作。我真的不知道是什麼問題,但在文本文件的最後一行不會顯示了,當我呼籲結構,我不覺得的話都放在正確的...從文本文件讀取行到結構C

void loadFile(char fileName[], Song *arr, int nrOf) { 

    FILE *input = fopen(fileName, "r"); 


    if (input == NULL) { 
     printf("Error, the file could not load!"); 
    } else { 

     fscanf(input, "%d", &nrOf); 
     fscanf(input, "%*[^\n]\n", NULL); 

     for (int i = 0; i < nrOf; i++) { 
      fgets(arr[i].song, sizeof(arr[i].song), input); 
      fgets(arr[i].artist, sizeof(arr[i].artist), input); 
      fgets(arr[i].year, sizeof(arr[i].year), input); 
     } 
     for (int i = 0; i < nrOf; i++) { 
      printf("%s", arr[i].song); 
      printf("%s", arr[i].artist); 
      printf("%s", arr[i].year); 
     } 
     rewind(input); 
     printf("The file is now ready.\n"); 

    } 

    fclose(input); 

} 

文本文件以第一行中的數字開始,以跟蹤列表中有多少首歌曲。因此我試着用這個:

fscanf(input, "%d", &nrOf); 
fscanf(input, "%*[^\n]\n", NULL); 

能夠在nrOf獲得數字後跳過第一行。

編輯: 這裏是結構:

typedef struct Song { 

char song[20]; 
char artist[20]; 
char year[5]; 

} Song; 

這裏是文本文件:

4 
Mr Tambourine Man 
Bob Dylan 
1965 
Dead Ringer for Love 
Meat Loaf 
1981 
Euphoria 
Loreen 
2012 
Love Me Now 
John Legend 
2016 

而且結構是動態分配的:

Song *arr; 
arr = malloc(sizeof(Song)); 
+1

這可能是有用的,如果你將包括的一個小文本摘錄或示例你正在閱讀的文件。這會讓我們(其他SO用戶)有機會看到你在做什麼,所以我們可以更好地爲你提供建議。 – SpencerD

+1

可能有助於查看「Song」的定義。 – RoadRunner

+0

如果你想讀取行,讀取行(* fgets *可以這樣),然後將它們解析爲字符串(* sscanf *,* strtok *,plain * for * char char *)。 – hyde

回答

2

有一個組合最後一行不打印的原因

的主要原因是最後一行(S)從來沒有閱讀

不應調用fclose()任何執行文件所在的路徑無法打開

沒有必要調用rewind()當下面的語句是fclose()

由於調用printf()Song陣列中的字段是輸出,一個接一個,這將導致很長的長單行輸出到終端,希望終端被設定爲經過這麼自動滾動科拉姆ns的輸出,但不能依賴。

輸出錯誤信息時,最好輸出到stderr而不是stdout。功能:perror()這樣做,並輸出操作系統認爲發生錯誤的原因。 (它通過參考errno選擇哪些錯誤消息,以輸出這一點。)

下面是關鍵問題:

如果輸入文件每行包含一個歌曲信息,則字段year要麼包含一個尾隨換行符或換行符不會被讀取。如果沒有閱讀換行符,則試圖輸入歌曲標題的fgets()的下一個呼叫將僅接收換行符,則所有後續字段(所有歌曲的)將逐漸進一步關閉。

建議閱讀一首歌領域後,使用循環來清除在輸入行的任何剩餘的字符,類似於:

int ch; 
while((ch = getchar(input)) && EOF != ch && '\n' != ch);