ページ 11

fread()の返し値はcountより小さい?

Posted: 2008年10月29日(水) 13:13
by みどり
Q: どんな場合、fread()の返し値はcountより小さいでしょうか。

fread()関数の説明(MS-VC++ helpから):
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
size_t fread(
void *buffer,
size_t size,
size_t count,
FILE *stream );

パラメータ
buffer
データの格納場所。

size
項目のサイズ (バイト単位)。

count
読み出す最大項目数。
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・

実際の問題として、ファイルに残るデータのbyte数がcount×size より遥かに多いに関わらず、
fread()の返し値はcountより小さいです。

可能性のある原因についてご教授お願い致します。

Re:fread()の返し値はcountより小さい?

Posted: 2008年10月29日(水) 13:30
by 御津凪
返す値は、<u>項目数</u>なので、最大 count までの値しか返しません。

つまり、 count が 5 、 size が 10 の時、読み出すbyte数は 50 ですが、返される値は 5 です。

読み込んだbyte数そのままを返したい場合は、size を 1、count を読み込む byte 数にすれば、読み込んだbyte数が返されます。

Re:fread()の返し値はcountより小さい?

Posted: 2008年10月29日(水) 13:39
by みどり
御津凪さま

早速ご返答ありがとうございます。
質問不明確で御免なさい!
まさに残る"項目数"はcountより大きいであるが、
返された数はcountより小さいケースです。
不思議に思いますが、原因は分かりません。
(以前、発生しなかった現象)

また宜しくお願い致します.

Re:fread()の返し値はcountより小さい?

Posted: 2008年10月29日(水) 13:56
by 御津凪
読み込むbyte数はどれくらいですか?
遥かに多い(MB単位ぐらい)場合、fread() 呼び出し一回では読みきれない場合があります。
(内部処理によりますし、元々エラーが発生しているのかもしれませんが)

対策として、こんな関数を作ってみました。
size_t readfile( void* buffer, size_t size, FILE* fp ){
	size_t rest = size; // 残り読み込みバイト数
	size_t read; // 読み込んだバイト数
	do{
		read = fread(buffer,1,rest,fp);
		rest -= read;
		if(read == 0){ // 読み込みが1バイトもされなかった場合、
			if(feof(fp)){ // EOF(ファイルの終端)に達した場合
				return rest; // 読み込まれなかったbyte数を返す。
			}
			else{ // EOF でない(つまりエラー)場合
				return (size_t)-1; // エラーを示す値を返す。
			}
		}
	}while(rest != 0);
	return 0; // 正常終了の 0 を返す。
}
動作確認はしてません。

Re:fread()の返し値はcountより小さい?(原因は分かった)

Posted: 2008年10月29日(水) 15:40
by みどり
御津凪 さま
丁寧なご指導ありがとうございます。

大きな誤りを犯してしまいました! .....Cではよくあるケースだと思います。

いまのbufferに当たるものは「ポインタ」ではなくて、「ポインタ」の「ポインタ」ですので

fread( buffer, size, count, stream );
ではだめなわけで、

fread( *buffer, size, count, stream );
ではなければならないことにやっと気づきました。

この「小さなミス」で、それ以降、理解不可能現象がぞくぞくと発生しました!

***************************************************
ただ、御津凪さまに示されたコードは参考価値が高くて、
他の場合にご利用させていただきます。

どうも有難うございました。