2012-03-23 18 views
0

私のプログラムがファイルからデータを読み込むのに問題があります。問題は、ファイルが現在空であることです。プログラムが実行されるたびに、books []の1つの配列が読み込まれ、後でそのコードに書き込まれます。 10個の構造体がすべてファイル内にあるときにはうまくいくとは思うが、ファイルが空で10個の構造体を読み込もうとするとクラッシュする。ファイルから未知数の構造体を読み取る - C

ファイルから(10まで)構造体の数が不明で読み込む方法はありますか?

struct stock 
{ 
    char name[31]; 
    int stock; 
}; 

int main (void) 
{ 
    stock books[10]; 

    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    fread(books, sizeof(struct stock), 10, fptr); 

    fclose (fptr); 
} 
+0

どこがクラッシュしますか?エラーは何ですか?これは奇妙なことにほぼ完全な問題の記述です。 – tbert

+0

ファイル形式を管理している場合(つまり、他の人が定義していない場合)、バイナリの代わりにテキスト形式(例:名前、行ごとに1つ)を使用することをお勧めします。これはもう少しコードを意味しますが、コードを一度書くだけです。ファイルはずっと使いやすくなります。 –

答えて

2

:それ以外の場合はループ

int main (void) 
{ 
    #define MAX_BOOKS 10 
    stock books[MAX_BOOKS]; 
    size_t cnt_books = 0; 
    FILE *fptr; 
    fptr = fopen("stock.dat", "rb"); 
    cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr); 
    fclose (fptr); 
    return 0; 
} 

をチャンクで読み取る完全なコードは次のようになります。

while (cnt_books = fread(books, sizeof(struct stock), MAX_BOOKS, fptr)) { 
     /* ... */ 
    } 
2

はい、あなたはそれを行うことができます。

  • あなたは、ファイルがあなたが読ん項目数をチェックする必要があり
  • 存在することを確認するfopenによって返された値をチェックする必要がある - size_tを戻り値fread
1

クラッシュ?これらの記述ではなく、ファイルが全くない限り、私は願っています。 nameフィールドはおそらく有効なC文字列ではないため、配列に有効なアイテムが10個あると仮定すると、クラッシュする可能性があります。私が好むだろうが

num = fread(books, sizeof(struct stock), 10, fptr); 

num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 

をそれはあなたがコードの多くを変更する必要がないことを意味するので

あなたが実際に読んで何を見つけ出す方法がです型名または配列サイズが変更されたイベント。それが可能だ場合

ファイルも開かない、あなたにもfopen戻り値をチェックする必要があります。あなたは、ファイル内の構造体の最大数を知っているし、メモリにそれらすべてを持っている余裕があれば

#include <stdio.h> 

typedef struct { 
    char name[31]; 
    int stock; 
} tStock; 

int main (void) { 
    tStock book[10]; 
    size_t num, i; 

    FILE *fptr = fopen ("stock.dat", "rb"); 
    if (fptr == NULL) { 
     num = 0; 
    } else { 
     num = fread (book, sizeof(*book), sizeof(book)/sizeof(*book), fptr); 
     fclose (fptr); 
    } 

    printf ("Read %d items\n", num); 
    for (i = 0; i < num; i++) { 
     printf (" Item %d is %s, %d\n", book[i].name, book[i].stock); 
    } 

    return 0; 
} 
0

コードはうまくいきます(ただし、それは行っていません)。 freadマニュアルページを参照してください - 読み込んだ項目の数を返します。

0
fptr = fopen("stock.dat", "rb"); 
if(fptr == NULL) 
{ 
    // error 
} 
else 
{ 
    for(int i=0; i<10 && !feof(fptr); i++) 
    { 
    fread(&books[i], sizeof(struct stock), 1, fptr); 
    } 
    fclose(fptr); 
} 
+0

私はfread関数の中で10の代わりに1を意味すると信じています –

+0

@ CodeChordsman確かに、私のコードは完全に間違っていて、自分自身にも気づいていました。修正をありがとう。 – Lundin

0

私はわからないんだけど、fread()がクラッシュするが、この場合では0である、読み項目の数を返すことになっていません。また、私はラインstock books[10];がコンパイルする方法を正確に理解していない、それはstruct stock books[10];でなければなりません。

私は二つのことを示唆している: 1.やるべき重要なことは、FPTRがNULLでないことを確認しているstruct stock books[10]; 2に交換してください。おそらく、ファイルを開くことができませんでした(おそらく同じディレクトリにないか、まだ存在しません)。その結果、fptrがNULLになり、freadで使用するとアプリケーションがクラッシュします。

+0

'ストックブック[10];'はC++コンパイラでコンパイルします – gbulmer

関連する問題