ページ 11

ファイルバッファーについて

Posted: 2011年2月09日(水) 12:50
by たく
はじめまして、
C言語についての質問です。
テキストファイルを読み込み、内容を修正後、上書き保存するプログラムの場合、
fgetsで行単位で取り込むためのバッファーはどのように設定すればよいでしょうか?

1.あらかじめ、大きめな配列を用意しておく
2.一度、ファイルを読み込み、最大容量を調べて領域を確保する
3.動的にメモリー領域を増やしながら、移動させていく
などの方法が有るかと思いますが、非力なマシンで、純粋なC言語で書くとすれば
どのような方法がよいでしょうか?

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 13:02
by softya(ソフト屋)
ファイルサイズ全体のサイズを調べて、freadでファイル全体を取り込むのではだめでしょうか?
MS-DOS時代から行われていた手法ですが。

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 14:54
by たく
softyaさま

早々に返信いただきありがとうございます。

用途として、主に
ラベル スペース データ 改行
といった構造のテキストの設定ファイルを対象に考えており
行単位の方が、後の処理が楽そうなのでfgetsを考えていました。
データーの内容が変更され、データ長も変わる場合があります。

ファイルサイズを調べるとは、fseek等で一度全体をなめて、
バッファサイズを決定すると言う方法でしょうか?

やはり、この方法が一見ばからしそうですが、確実なんでしょうか?

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 15:11
by softya(ソフト屋)
テキストエディタ風な物と考えると一行毎にバッファを持つリスト構造が便利かもしれません。
一行バッファは増加する毎に確保しなおす必要がありますが、この方法なら行の挿入や削除にも有利です。
サイズを調べるには、一行のバッファを固定長(32768バイト)とかにして実際に読み込んで調べる方法が簡単でしょう。
読み込み後は、固定バッファから一行毎にmallocしたバッファに転送します。

>ファイルサイズを調べるとは、fseek等で一度全体をなめて、
>バッファサイズを決定すると言う方法でしょうか?

同じか小さくなるなら良いのですが、大きくサイズが変わる(増える)ならあまり良い方法とは言えませんね。

参考として一括読み込みの関数を書いておきます。

コード:

static char *AllFileLoad(char *fname,int *psize)
{
	FILE *fp;
	char *buf = NULL;
	
	//	ファイルオープン
	fopen_s( &fp, fname, "rb" );
	if( fp != NULL ) {
		//	ファイルサイズを調べる。
		fseek( fp, 0, SEEK_END );
		*psize	= ftell( fp );
		fseek( fp, 0, SEEK_SET );
		//	ファイルバッファを確保。
		buf = (char*)malloc( (*psize) + 1 );
		//	ファイルを全部読み込む
		fread( buf, 1, (*psize) , fp );
		buf[(*psize)] = 0x00;	//文字列の終わり。
		//	ファイルを閉じる
		fclose(fp);
	}
	
	return buf;
}

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 17:26
by non
私が昔、エディタを作ったときは、1行に80バイトをとりました。80バイトをオーバーすると、再び80バイト増えるようにしました。1行分をノードとした双方向リンクで繋ぎました。
struct{
int mojisu;

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 17:26
by non
私が昔、エディタを作ったときは、1行に80バイトをとりました。80バイトをオーバーすると、再び80バイト増えるようにしました。1行分をノードとした双方向リンクで繋ぎました。

Re: ファイルバッファーについて

Posted: 2011年2月09日(水) 18:14
by たく
みなさま、ご指導いただきありがとうございました。
以前、VC++6.0などで、いくらかコードを書いていたんですが、今回、Cだけで書く必要があって、分からなくなってしまいました。
C++なら、STLのString vector など何でも使えたので、なんとも思わなかったんですが、

結局、汎用的な使用なら、メモリーバッファの拡張、単純な用途ならファイルの2度読みあたりが簡単と言うことでしょうか