ページ 11

ファイルの読み込みについて

Posted: 2011年4月14日(木) 18:14
by fulls
C++で自作のバイナリファイルの読み込みをしています。
バイナリエディタで 00 のところで読み込みが止まってしまって困っています。
何かいい方法はありませんか。
コード↓

コード:

#include<iostream>
#include<conio.h>
#include<fstream>

using namespace std;

#define PackingName "thf00s.dat"			//読み取りファイル名
#define MARK "#CS#"						    //セパレーター 


int main(){
	//変数

	//ファイルサイズ
	size_t FileSize;
	//ファイル数
	int amount;

	std::ifstream dat;
	//読み込み
	dat.open(PackingName,std::ios::in | std::ios::binary);
	//取得確認
	if(dat.fail()){
		cout<<"ファイルがありません"<<endl;
		_getch();
		return 0;
	}

	//ファイルの個数の読み込み
	char buf[16];
	dat.get(buf,16);

	

	//サイズ取得
	FileSize=(size_t)dat.seekg(0,std::ios::end).tellg();
	cout<<"ファイルサイズは "<<FileSize<<" Bです。"<<endl;

	//ポインタを最初に戻す。
	dat.seekg(0,std::ios::beg);

	//サイズ分だけメモリを確保
	char *Buffer = new char [FileSize];

	//読み込み
	dat>>Buffer;
	cout<<Buffer<<endl;
	cout<<"文字数は"<<strlen(Buffer)<<endl;
	//#CS#を探す
	strtok(buf,MARK);
	
	//charからintに変換
	amount=atoi(buf);
	cout<<"ファイル数は"<<amount<<"個です。"<<endl;


	//終了作業
	delete [] Buffer;
	dat.close();

	_getch();
	return 0;
}
よろしくお願いします。
多分EOFと勘違いしているのかなーとか思うのですが...

Re: ファイルの読み込みについて

Posted: 2011年4月14日(木) 19:45
by fulls
追記です。

バイナリファイルの中身は、画像データをまとめたもので、ファイルの頭に画像の個数が入っていて、その後から画像名、容量、画像データの順で入っています。
データの句切れ目には"#CS#"という文字がいれてあります。

環境は、
Windows7
Microsoft Visual Studio 2010 Pro
です。

Re: ファイルの読み込みについて

Posted: 2011年4月14日(木) 20:56
by bitter_fox
yucky001 さんが書きました: バイナリエディタで 00 のところで読み込みが止まってしまって困っています。

コード:

	std::ifstream dat;

	//ファイルの個数の読み込み
	char buf[16];
	dat.get(buf,16);

	//サイズ分だけメモリを確保
	char *Buffer = new char [FileSize];

	//読み込み
	dat>>Buffer;
	cout<<Buffer<<endl;
	//#CS#を探す
	strtok(buf,MARK);

	amount=atoi(buf);
	cout<<"ファイル数は"<<amount<<"個です。"<<endl;
二回ファイルから読み込んでますがそのどちらで読み込みが止まってしまうのですか?

またBufferはchar*なので00(多くの環境で'\0'と同義)までしか出力されませんよ。

それから蛇足になりますが
atoi関数は数字でない文字があった場合はそこで処理を終了してそこまでの数値を変換して返すのでわざわざstrtok関数でNULLに換える必要はないですよ。
http://ja.wikipedia.org/wiki/Atoi

Re: ファイルの読み込みについて

Posted: 2011年4月14日(木) 21:03
by fulls
返信ありがとうございます。

コード:

    //ファイルの個数の読み込み
    char buf[16];
    dat.get(buf,16);
は、消し忘れです。
すいません。

>またBufferはchar*なので00(多くの環境で'\0'と同義)までしか出力されませんよ。
では、どうすれば良いのでしょうか。
パッと思いついたのがこの方法だったもので...

atoiの方はこの前何かの本で読み、直し忘れていました。
すいません。

Re: ファイルの読み込みについて

Posted: 2011年4月14日(木) 22:08
by YuO
opeartor>> (basic_istream<charT, traits>&, charT *)やoperator<< (basic_ostream<charT, traits>&, const charT *)は,「文字列」の入出力を行う関数です。
つまりは,charT() (iostreamでは'\0') で終端します。

バイナリデータを取り扱いたいのであれば,readsomeで読み取る必要がありますし,writeで書き込む必要があります。
ただし,std::coutには,「何を出力したいのか」をハッキリさせた方が良いです。バイナリデータなんて出力させてもしょうがないので。


同様の理由から,strlenやstrtokは使えません。
これらは,やはり文字列を対象に使う物です。
さらに,データの区切りを#CS#だとしても,それを探す事で区切りを見つけるのでは,その文字列がデータに入っていれば正しくデータが読み取れません。
可変長で全ビットパターンが出てくる場合は,データ長を読み取ってその値を使って取り扱う必要があります。

Re: ファイルの読み込みについて

Posted: 2011年4月15日(金) 05:25
by fulls
YuOさん、返信ありがとうございます。

教えていただいたreadsomeを調べてみます。
あと、私は今、ゲームを作っていて、それで使う画像をパッキングしたいと思いこのようなプログラムを書いているので、coutで出力するのはなんらかのデータが読み取れているか確認するために行っています。

Re: ファイルの読み込みについて

Posted: 2011年4月17日(日) 13:17
by fulls
読み込み自体はread関数でできてました。
ただ表示するときにEOFで終わっていたようです。
ありがとうございました。