1

ファイル内の各行の新しい構造体にメモリを割り当てようとしていますが、ファイルが空の場合でも、ループはメモリを 1 回割り当てます。問題はwhile(!feof(file))を使用していますが、whileループの代替チェックがわかりません。

ループは次のようになります。

while(!feof(f))
{
    p = (struct PlayerTime*)malloc(sizeof(struct PlayerTime));
    head = p;
    fscanf(f, "%f %s", &p->seconds, p->name);
    p = p->next;
}

ポインターと構造体はすべてループの前に定義されています。ファイルに何もない場合にループしないようにする方法がわかりません。

4

2 に答える 2

0

これはうんざりするほど議論されてきました。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;
于 2013-10-05T23:06:23.253 に答える
0
  1. feof(f)EOFまだ攻撃を受けていないと言う
  2. fscanfヒットしEOFて失敗する
  3. feof(f)EOFヒットしたため、ループを停止します

正しいアプローチ:

while (fscanf(f, "%f %s", &p->seconds, p->name) == 2) {
    ...
}

ヒント: また、いつ、どのようにメモリを割り当てる必要があるか、どのようなシナリオが発生する可能性があり、どのように処理する必要があるかについても、より多くの時間をかけて考えてください。

于 2013-10-05T23:04:07.167 に答える