我正在尝试从列表中读取行到我的结构,它几乎正在工作。我不确定问题是什么,但是当我调用结构时,文本文件的最后一行不会出现,我不认为这些单词是正确的...
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));
答案 0 :(得分:2)
有最后一行不打印的原因组合
主要原因是最后一行从未被阅读
不应在文件无法打开的任何执行路径中调用fclose()
当下一个语句为rewind()
fclose()
由于对printf()
数组中的字段的Song
的调用是一个接一个地输出,这将导致向终端输出长的长行,希望终端设置好在这么多输出列之后自动滚动,但这不能依赖。
输出错误消息时,最好将其输出到stderr
,而不是stdout
。函数:perror()
执行该操作并输出操作系统认为发生错误的原因。 (它通过引用errno
来选择要输出的错误消息。)
以下是关键问题:
如果输入文件每行包含一个歌曲信息,则字段year
将包含尾随换行符或者不会读取换行符。如果没有读取换行符,则下一次试图输入歌曲标题的fgets()
只会收到换行符,然后所有后续字段(所有歌曲)将逐渐关闭。
在阅读歌曲字段后建议,使用循环清除输入行中的任何剩余字符,类似于:
int ch;
while( (ch = getchar( input )) && EOF != ch && '\n' != ch );