これはうんざりするほど議論されてきました。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;