2017-01-22 64 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);