2017-08-14 1 views
0

私は、データファイルを読み込む機能を持つ大きなプロジェクトに取り組んでいます。ただし、特定のテストコードでは、そのファイルは存在しないため、作成時に空のテキストファイルが作成されます。私は、このイベントを補うために、次のコードを書いた:空のファイルを読み取っているときにfscanfがクラッシュする

typedef struct system_boot_status_s{ 
    char timestamp[18]; 
    int power_down_type; 
    int power_down_cause; 
    int boot_number; 
    int antenna_deployed; 
    int images_captured; 
    int beacon_count; 
}system_boot_status_t; 

//////////////////////////////// 

// Read the boot status info into the boot status struct 
    ret = fscanf(f, "%s %d %d %d %d %d %d", 
    bootstatus->timestamp, 
    bootstatus->power_down_type, 
    bootstatus->power_down_cause, 
    bootstatus->boot_number, 
    bootstatus->antenna_deployed, 
    bootstatus->images_captured, 
    bootstatus->beacon_count); 

    if (ret != 7) // if 7 items weren't read 
    { 
    // Make sure all boot status members are set to 0 
    snprintf(bootstatus->timestamp, BOOT_INFO_LEN, "xx-xx-xx-xx-xx-xx"); 
    bootstatus->power_down_type = 0; 
    bootstatus->power_down_cause = 0; 
    bootstatus->boot_number = 0; 
    bootstatus->antenna_deployed = 0; 
    bootstatus->images_captured = 0; 
    bootstatus->beacon_count = 0; 

    return -1; 
    } 

私は関数fscanfは、読み込むものの数を返すことを知っているが、私はこのプログラムを実行し、それが空のファイルに達したときに、私のプログラムだけでフリーズします。私はEOFでやっていなければならないことが何か不足していますか?誰か助けてくれますか?

+1

「power_down_type」などのこれらの変数にはどのようなタイプがありますか? 'int'? 'int *'? –

+3

ファイルが正しく開くことをどのように知っていますか? '&' address-of演算子が間違っていて、 'struct'にポインタが含まれていることをどうやって知っていますか?問題を示す[最小、完全、および検証可能な例](http://stackoverflow.com/help/mcve)を投稿してください。 2番目のブロックでは、あなたはポインタではないことを示唆する 'bootstatus-> power_down_type = 0;'を持っています。 –

+0

typedef struct system_boot_status_s { char timestamp [18]; int power_down_type; int power_down_cause; int boot_number; int antenna_deployed; int images_captured; int beacon_count; } system_boot_status_t; –

答えて

1

fscanf(3番目と3番目)の引数は、適切な型へのポインタでなければなりません。最も単純なケースでは使うことができ&オペレータ

ハードの問題、入力された短いint型(文字/バイト)からの自動キャストは

これは、宣言に依存
ret = fscanf(f, "%s %d %d %d %d %d %d", 
    bootstatus->timestamp, // string 
    &bootstatus->power_down_type, // int 
... 
); 

、唯一の宣言は、私のサンプル

では許可されていないintです

整数がない場合は、一時変数を使用してください。この例では、タイムスタンプが(ようにバイトと)異なる整数型の一種で深刻な問題を与える。このルールの

int tmp1; 

    ret = fscanf(f, "%s %d %d %d %d %d %d", 
     bootstatus->timestamp, 
     &tmp1 , 
    ... 
    ); 

    bootstatus->power_down_type = tmp1; 

破断がある(システムに依存して、コンパイラなど)

私の答えは、仮定にない基づいていますこの構造体の実際の宣言は、執筆時点で不明です

+2

'timestamp'は大丈夫でした。文字列です。コメントは' // int'ではありません。 –

+0

私は答えを –

+1

に変更しました。これは '%s'として読み込まれます。配列へのポインタは最初の文字へのポインタと同じですが、正しい使い方ではないため動作します。 –

0

変数へのポインタ(int*)を受け入れる関数にint(値による)を渡しています。

変数のアドレスを渡すだけで、もはやフリーズすることはできません。 変数アドレスを解除するには、&varを入力します。

ret = fscanf(f, "%s %d %d %d %d %d %d", 
    bootstatus->timestamp, 
    bootstatus->power_down_type, 
    bootstatus->power_down_cause, 
    bootstatus->boot_number, 
    bootstatus->antenna_deployed, 
    bootstatus->images_captured, 
    bootstatus->beacon_count); 

ret = fscanf(f, "%s %d %d %d %d %d %d", 
    bootstatus->timestamp, 
    &bootstatus->power_down_type, 
    &bootstatus->power_down_cause, 
    &bootstatus->boot_number, 
    &bootstatus->antenna_deployed, 
    &bootstatus->images_captured, 
    &bootstatus->beacon_count); 

ではなく、文字列へ

へ! &timestamptimestampと同じアドレスを指しているという事実にもかかわらず。

関連する問題