ページ 11

ifstreamで

Posted: 2012年3月18日(日) 22:51
by SUE
ファイル読み込みをしようと思ってこんなコードを書きました。

コード:

using namespace std;

int main(){

	const char* name = "common.dat";

	ifstream ifs( name, ifstream::binary );

	ifs.seekg( 0, fstream::end );
	unsigned end = ifs.tellg();

	ifs.clear();

	ifs.seekg( 0, fstream::beg );
	unsigned beg = ifs.tellg();

	unsigned size = end - beg;

	char* buf = new char[ size ];
	memset( buf, 0, size );

	ifs.read( buf, size );

	cout << buf;

	delete[] buf;
	while(1){
		;
	}
	return 0;
}
入力ファイル

コード:

1
others.dat
eof
出力

コード:

1
others.dat
eofォォォォォォォォ・
と、こんな感じにゴミがくっついてきてしまいます。ifstream::binaryを外せばなくなりますが、そういうわけにも行かない状況です。
(しかも外したとて、ファイル中に改行がないと同じようにゴミがつきます。まあ今回は無視して大丈夫ですが・・・)

どうすればこのゴミを消せるのかお教え願います。

Re: ifstreamで

Posted: 2012年3月18日(日) 23:03
by a5ua

コード:

cout << buf;
は、bufをゼロ終端文字列とみなして出力するので、
bufのサイズは、ヌル文字'\0'の分を考慮して、size + 1としなければならないと思います。

もしくは、1文字ずつ出力することも考えられます。

コード:

for (int i = 0; i < size; ++i) cout << buf[i];

Re: ifstreamで

Posted: 2012年3月18日(日) 23:10
by beatle
根本的な原因は、ifs.readでbufにデータを読み込んだあと、NULL文字をbufに書き込んでいないことにありますね。
bufのサイズを読み取るバイト数+1にするのと同時に、読み取ったバイト数の次のバイトにNULL文字を書き込むのを忘れないようにしましょう。
(memsetでNULL文字を書きこんでいるのだ!というのであればそれで結構です)

Re: ifstreamで

Posted: 2012年3月18日(日) 23:19
by SUE
>>a5uaさん
基本的なとこでしたね・・・見落としていました。

>>beatleさん
言われた通りにして成功しました。
memsetで0クリアしてるのにそれは変じゃね? とか思ってしまいましたが、ifstream::read自体が余計なゴミを引き連れていました。

お二方ありがとうございました。こういう、簡単だけど根源的な問題はやはり大事にすべきですね。
オフトピック
どんなサイトを探しても以上を指摘してるところは無かったけどね・・・

Re: ifstreamで

Posted: 2012年3月19日(月) 01:20
by たかぎ
原因はすでに指摘されている通りです。
一応参考までに、ファイルの内容をすべて読み込む方法も書いておきます。

コード:

std::ifstream ifs(name);
std::ostringstream oss;
oss << ifs.rdbuf();
std::string str(oss.str());  // ファイルの内容が取得できた。