ページ 11

マップのロード

Posted: 2011年8月28日(日) 16:56
by maku02
以前、セーブファイルの作り方でお世話になりました。

今回、2Dマップの構造をエクセル形式のファイルから読み取る関数を作ろうとしていたのですが、
class MAPの持つ変数map_wide,map_lengthに値が入りません。
ブレークポイントを作って確認してみたのですが、
まずファイルをちゃんと読みこんでいるのかの確認の仕方がわかりませんし、
map_wideについても-858993664などという値になって確実に読み込みに失敗しています。
以下のコードのどこが問題なのかを教えてください。
ファイル入出力についてはいまだに疎いです。

コード:

void Map::map_load()
{
	ifstream ifs;
	ifs.open("sample.csv");
	ifs.getline((char*)&map_wide,sizeof(int),',');//マップの幅読み込み
	ifs.getline((char*)&map_length,sizeof(int),',');//マップの高さ読み込み
	ifs.ignore(INT_MAX,'\n');
}
"sample.csv"についてはファイル添付の仕方がわかりませんでしたので、内容だけコピペしますと、

20,24,32,32,1,8
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
255,255,0,0,0,0,0,0,0,255,255,0,0,0,0,0,0,0,255,255
255,255,49,49,49,49,49,49,49,255,255,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,255,255,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,255,255,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,255,255,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,255,255,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,0,0,49,49,49,49,49,49,49,255,255
255,255,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,49,255,255
255,255,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,255,255
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
255,255,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,255,255,51,51,51,51,51,51,51,255,255
255,255,51,51,51,51,51,51,51,1,1,51,51,51,51,51,51,51,255,255
255,255,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,255,255
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255

です。
よろしくお願いします。

Re: マップのロード

Posted: 2011年8月28日(日) 17:18
by softya(ソフト屋)
これは、文字列を数値として強引にロードしているように見えますが。
csvですからテキスト(文字列)ですので、まず文字列として読み込んで数値変換してください。

Re: マップのロード

Posted: 2011年8月28日(日) 17:32
by maku02

コード:

void Map::map_load()
{
    char c1[10];
    char c2[10];
    ifstream ifs;
    ifs.open("sample.csv");
    ifs.getline(c1,sizeof(int),',');//マップの幅読み込み
                     //↑↓読み込むサイズはこのままint型?
    ifs.getline(c2,sizeof(int),',');//マップの高さ読み込み
    ifs.ignore(INT_MAX,'\n');
}
これでc1とc2内の文字列をint型に変換してmap_wideとmap_lengthに入れればいいのでしょうか。
問題は、文字列を数値に変換する方法を知らないのです。
よろしければ、その方法も教えていただきたいです。

Re: マップのロード

Posted: 2011年8月28日(日) 17:32
by softya(ソフト屋)
あっifstreamだから、>>演算子を使えば解決なのでは?

コード:

void Map::map_load()
{
    ifstream ifs;
    char skip;
    ifs.open("sample.csv");
    ifs >> map_wide >> skip >> map_length;
}
型変換も自動です。

Re: マップのロード

Posted: 2011年8月28日(日) 17:50
by maku02
すみません。以下のコードに書き直してみたのですが、やはり、どの変数にも値が入っていませんでした。

コード:

void Map::map_load()
{
	ifstream ifs;
	char skip;
	ifs.open("sample.csv");
	ifs>>map_wide>>skip>>map_length;
	ifs.ignore(INT_MAX,'\n');
}
やはりファイルの読み込みが出来ていないのでしょうか。
それと書き忘れていましたが、上記のmap_load()は以下のMAPコンストラクタで行っています。

コード:

Map::Map(int n,int u,string s):
map_n(n),used_map_tip(u),map_name(s)
{
	map_xy = 0;	//画面左上に描写すべきマップのマス座標
	map_x = 0;
	map_y = 0;
	map_load();
}
コンストラクタ内でやっているのがいけないのかと思い、main関数で改めて行ってみましたが結果は変わらず。

ファイルを開けたかどうかはどう見ればいいのでしょうか

Re: マップのロード

Posted: 2011年8月28日(日) 17:55
by softya(ソフト屋)
is_openでチェックしてください。
「is_open」
http://www.cplusplus.com/reference/iost ... m/is_open/

Re: マップのロード

Posted: 2011年8月28日(日) 18:20
by maku02

コード:

void Map::map_load()
{
	ifstream ifs;
	char skip;
	ifs.open("sample.csv");
	ifs>>map_wide>>skip>>map_length;//ブレークポイントをこの行に置いていた
	ifs.ignore(INT_MAX,'\n');
}
ごめんなさい。ブレークポイントの設置個所を間違えていたせいで、値が代入する前のものを見ていました。
ちゃんとmap_wide,map_length,skipには適切な値が入っていました。
この後のマップ構造の読み込みもwhile使って同じやり方でいけるのだと思います。

ところで、ifs.open(string);
みたいに開くファイルのパスを変数で管理する方法は無いでしょうか。
実のところ、先程のMAPコンストラクタの引数にあったmap_nameに"sample.csv"を与えて、
ifs.open(map_name);と出来ないかと思っていたのでしたが、やはり出来ないようですね。

Re: マップのロード

Posted: 2011年8月28日(日) 18:31
by softya(ソフト屋)
こういう話でしょうか?

コード:

#include <fstream>
#include <iostream>
#include <string>
using namespace std;

int main(void) {
	ifstream ifs;
	char skip;
	int map_wide,map_length;
	string map_name("sample.csv");

	ifs.open(map_name.c_str());
	ifs >> map_wide >> skip >> map_length;
	cout << map_wide << "," << map_length << endl;
}

Re: マップのロード

Posted: 2011年8月28日(日) 18:37
by maku02
えっと、

コード:

void Map::map_load()
{
	ifstream ifs;
	char skip;
	bool b = false;
	ifs.open(map_name);
	b = ifs.is_open();
	ifs>>map_wide>>skip>>map_length;
	ifs.ignore(INT_MAX,'\n');
}
このコードで試してみましたが、
すみません。
ちゃんと出来ましたね。
しっかり確認せずに聞いてしまって申し訳ありません。

softyaさん、ありがとうございました。

取り敢えず問題は解消されたのでこれにて解決とさせていただこうと思いますが、最後にもう一つ。
softyaさんの示された

コード:

ifs.open(map_name.c_str());
とこちらで試した

コード:

ifs.open(map_name);
では何か違いがあるのでしょうか。

Re: マップのロード

Posted: 2011年8月28日(日) 18:44
by softya(ソフト屋)
環境次第では
ifs.open(map_name);
でOKなのですが、
ifs.open(map_name.c_str());
じゃないと通らない環境もあると思います。

fstreamとstringの実装次第です。C++0x=vc++2010ならOKなのかな?

Re: マップのロード

Posted: 2011年8月28日(日) 18:54
by maku02
という事はなるべくなら
ifs.open(map_name.c_str());
の方が良いということでしょうか。

取り敢えず解決タグを付けさせて貰います