这已经被讨论得令人作呕;feof
不会告诉您文件是否会在下一次读取时完成,而是告诉您是否已尝试读取并且由于文件结束而失败。
在您的情况下,解决方案可以是检查读取是否失败(通过检查 的返回值fscanf
),并在这种情况下释放结构;这也使您的代码更加健壮,因为它还会检查 EOF 以外的错误(例如 IO 错误、无效数据格式……)。
顺便说一句,p = p->next
不会做你所期望的。如果您正在“即时”构建一个链表,您可以执行以下操作:
// Allocate the space for the first element
struct PlayerTime *head=malloc(sizeof(*head));
// p will always point to a pointer to the element to be filled;
// let's start with the head
struct PlayerTime **p=&head;
// Try to read
while(fscanf(f, "%f %s", &((*p)->seconds), (*p)->name)==2)
{
// If we are here, the last read was successful
// Move p to the pointer to the next element
p = &((*p)->next);
// ... and allocate the space for such element
*p = malloc(sizeof(**p));
}
// After exit, there's an extra element that we allocated but we couldn't read
// Free it
free(*p);
// And put the relevant pointer to NULL
// (it will terminate the list, or set head to NULL if no element has been read)
*p=NULL;