質問
プログラムを実行して製品リストを表示することを選択すると、何も印刷されません。しばらくして、私はその値を見つける fl_size
常に0です。これはなぜですか?
void view_prdct_code_list() {
FILE *stock = fopen("stock.dat","r+");
assert(stock);
int fl_size=ftell(stock);
int prd_size= sizeof(product);
int quantity= fl_size/prd_size;
printf("fl_size=%d",fl_size);
fseek(stock,0,SEEK_SET);
prdct cprd= (product *)malloc (sizeof(product)*quantity);
assert(cprd);
int i;
fread(cprd,prd_size,quantity,stock);
for (i=0;i<quantity;i++){
printf("PRODUCT CODE: %d\n",cprd->code);
}
free(cprd);
fclose(stock);
}
解決
ftell
ファイルの合計サイズを返しません;これは現在の値を返します 読み取りまたは書き込み位置 ファイル内。あなたは電話します ftell
ファイルを開いた直後に、その位置がファイルの先頭になります。次のいずれかを使用できます fseek(stock, 0, SEEK_END)
呼び出す前に最後まで追求するには ftell
, 、または、レイヤーをドロップダウンして使用することができます fstat(fileno(stock))
OSから直接ファイルサイズを取得します。
その他の注意事項:
- パイプから読み込んでいる場合、これらのオプションはどちらも機能しません。(一般的には、ファイルアクセス操作のすべての成功を確認する必要があります。)
fread
あなたがそれを要求しても、ファイル全体を一括して読むことは保証されません。- 'Alk'が指摘するように,
ftell
aを返しますlong
, ではなく、int
. - この明らかにバイナリファイルをmodeで開く必要があります
"r+b"
. - ファイルヘッダーのないバイナリファイル(特に マジックナンバー, 、少なくとも4バイトの、オフセットゼロで)は悪いことです。
- の戻り値をキャストしないでください
malloc
.(これはC++で行う必要がありますが、Cでは不要なだけではありません, バグを隠すことができます.)
他のヒント
のmanページをチェック ftell
, たとえば、この1つ: http://linux.die.net/man/3/ftell
ここに関連する部分があります: "Ftell()関数は、streamが指すストリームのファイル位置インジケータの現在の値を取得します。"
ファイルを開くと、カーソル位置が先頭になります。したがって、開始からの距離はゼロになります。したがって ftell
ゼロを返します。
ファイルのサイズを見つけるには、このリンクを参照してください: Cでファイルのサイズを取得するにはどうすればよいですか?.ここに短いスニペットがあります:
fseek(fp, 0L, SEEK_END);
sz = ftell(fp);
必ず電話してください fseek(fp, 0L, SEEK_SET);
上記の後。
Because ftell
returns the size from the beginning to the current position of the file.
fseek(stock,0,SEEK_SET);
Means you set the position to the first bite of the file.
Also you gotta set fl_size=ftell(stock);
after the fseek
.