敵データの読み込みについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ひよこ

敵データの読み込みについて

#1

投稿記事 by ひよこ » 15年前

敵データを読み込もうとしたら、一回目は成功なんですが、2回目のデータが違くなってしまます。
おそらく2回目のアドレス関係でだめだと思うのですが、どこが悪いのでしょうか?
void load_enemy_data(){
		int num,i,fp;
	char fname[32]={"../dat/csv/story.csv"};
	int input[64];
	char inputc[64];

	//	実態を作る。
	enter_enemy_t *new_enter_enemy; 
	enter_enemy_t *now_enter_enemy;

	fp = FileRead_open(fname);//ファイル読み込み
	if(fp == NULL){
		printfDx("read error\n");
		return;
	}
	for(i=0;i<2;i++)//最初の2行読み飛ばす
		while(FileRead_getc(fp)!='\n');

	num=0;
	
	new_enter_enemy = new enter_enemy_t;
	new_enter_enemy->next=NULL;
	
	//	最初の処理なら。
	if( head_enter_enemy==NULL ) {
	//	最初の敵データ
	head_enter_enemy = new_enter_enemy;
	} 
	else
	{
	//	リストの最後を探す。
	now_enter_enemy = head_enter_enemy;
	while( now_enter_enemy->next!=NULL ) {
		now_enter_enemy = now_enter_enemy->next;
	}
	//	リストの最後に接続する。
	now_enter_enemy->next = new_enter_enemy;
	//now_enter_enemy=NULL;
	}
	while(1){
		for(i=0;i<64;i++){
			inputc=input=FileRead_getc(fp);//1文字取得する
			if(inputc=='/'){//スラッシュがあれば
				while(FileRead_getc(fp)!='\n');//改行までループ
				i=-1;//カウンタを最初に戻して
				continue;
			}
			if(input==',' || input=='\n'){//カンマか改行なら
				inputc='\0';//そこまでを文字列とし
				break;
			}
			if(input==EOF){//ファイルの終わりなら
				goto EXFILE;//終了
			}
		}
		switch(num){
			case 0:	new_enter_enemy->count	=atoi(inputc);break;
			case 1:	new_enter_enemy->pattern	=atoi(inputc);break;
			case 2:	new_enter_enemy->knd		=atoi(inputc);break;
			case 3:	new_enter_enemy->x		=atof(inputc);break;
			case 4:	new_enter_enemy->y		=atof(inputc);break;
			case 5:	new_enter_enemy->spd		=atof(inputc);break;
			case 6:	new_enter_enemy->wait	=atoi(inputc);break;
		}
		num++;
		if(num==7){
			num=0;
			//new_enter_enemy =NULL;
			new_enter_enemy = new enter_enemy_t;
			new_enter_enemy->next=NULL;
			//	最初の処理なら。
			if( head_enter_enemy==NULL ) {
				//	最初の敵データ
				head_enter_enemy = new_enter_enemy;
			} 
			else
			{
				//	リストの最後を探す。
				now_enter_enemy = head_enter_enemy;
				while( now_enter_enemy->next!=NULL ) {
					now_enter_enemy = now_enter_enemy->next;
				}
				//	リストの最後に接続する。
				now_enter_enemy->next = new_enter_enemy;
				//now_enter_enemy=NULL;
			}
		}
	}
EXFILE:
	FileRead_close(fp);
}

non

Re:敵データの読み込みについて

#2

投稿記事 by non » 15年前

>敵データを読み込もうとしたら、一回目は成功なんですが、2回目のデータが違くなってしまます。
どういう意味でしょうか?
1個目のデータはリストに追加されるが、2個目からのデータは繋がらないということですか?
仮にそのとき、どうやってデータを確認しましたか?
それとも、load_enemy_dataを2回呼び出したときという意味でしょうか?

ひよこ

Re:敵データの読み込みについて

#3

投稿記事 by ひよこ » 15年前

呼び出したときに、csvの1行目のところはうまくいっているのですが、2行目がうまく代入できません。

non

Re:敵データの読み込みについて

#4

投稿記事 by non » 15年前

リストのつなげ方のみ見れば、間違いは見あたりませんでした。
ただ、whileの前で1個のノードを作成するわけですが、load_enemy_dataを1度しか呼び出さない
のなら、「最初の処理なら」の部分だけでいいはず。また、whileでデータを格納後に2個目以降の
ノードを作成しているけど、これだと、必ず最後に空のノードができることになると思うけど
それでいいのでしょうか?

ひよこ

Re:敵データの読み込みについて

#5

投稿記事 by ひよこ » 15年前

連結リストなんで、つないでNULLを探します。

non

Re:敵データの読み込みについて

#6

投稿記事 by non » 15年前

>連結リストなんで、つないでNULLを探します。
そんなことは、尋ねていません。
とにかく、添付されたプログラムには無駄があるけど、間違っていないと言ってます。
間違いは、添付された部分以外にあります。

ひよこ

Re:敵データの読み込みについて

#7

投稿記事 by ひよこ » 15年前

必ず最後に空のノードができる
>>先がないもの(nextにNULL)ができるってことじゃないのですか?
必ず最後に空のノードができることになると思うけど
>>これが3つめのデータですか?

無駄があったんですか・・・・
間違いはあると思ったのです。
csvが下のようになっているのですが、
/カウンタ,移動パターン,敵の種類,x座標,y座標,スピード,待機時間
/cnt,pattern,knd,x,y,spd,wait
60,0,0,200,-20,0,800,
60,0,0,200,-20,0,80,
実際のデータ 2つしか読んでないのに3つあります。
head_enter_enemy = 0x022c13b8 {
x = 200.00000000000000、y = -20.000000000000000、next = 0x022f1430、}
head_enter_enemy=>next {x=0.00000000000000000 y=200.00000000000000 next 0x022f14a8}
(head_enter_enemy)->next {x = -6.2774385622041925e+066 y = -6.2774385622041925e+066 next = 0x00000000}

non

Re:敵データの読み込みについて

#8

投稿記事 by non » 15年前

> 必ず最後に空のノードができる
> >>先がないもの(nextにNULL)ができるってことじゃないのですか?

未使用の(データを格納していない)ノードです。
もちろん中身はゴミですから。nextだけはNULLが格納されていますけど。


> 必ず最後に空のノードができることになると思うけど
> >>これが3つめのデータですか?

恐らくそうでしょう。


>
> 無駄があったんですか・・・・
> 間違いはあると思ったのです。
> csvが下のようになっているのですが、
> /カウンタ,移動パターン,敵の種類,x座標,y座標,スピード,待機時間
> /cnt,pattern,knd,x,y,spd,wait
> 60,0,0,200,-20,0,800,
> 60,0,0,200,-20,0,80,
> 実際のデータ 2つしか読んでないのに3つあります。
> head_enter_enemy = 0x022c13b8 {
> x = 200.00000000000000、y = -20.000000000000000、next = 0x022f1430、}
> head_enter_enemy=>next {x=0.00000000000000000 y=200.00000000000000 next 0x022f14a8}
> (head_enter_enemy)->next {x = -6.2774385622041925e+066 y = -6.2774385622041925e+066 next = 0x00000000}

2つめのデータ x=0.00000000000000000 y=200.00000000000000 と一つずつずれているのが気になります。
ああ。。。csvデータの最後の,が原因か。

ひよこ

Re:敵データの読み込みについて

#9

投稿記事 by ひよこ » 15年前

enter_enemy_t *nextだからNULL(中身の入っていないデータ)ができるのですか。
やっぱり連結リストだからですよね?
csvデータの最後の,が原因か。
>>なぜですか?

サイト愛用者

Re:敵データの読み込みについて

#10

投稿記事 by サイト愛用者 » 15年前

while分の中のif( head_enter_enemy==NULL )はアルゴリズム上有り得ないので不要です。
従って対応するelseの記述も削除します。

更にnonさんの仰るように次のレコードの有無に関わらずノードを作成しているので最後のノードは必ずゴミの入ったノードになります。よってこのことを前提に処理を行う必要があります。
あるいはswitchのcase0の部分で新規ノードを作成するなど未然に解決します。
いずれにしてもメモリをアロケートしたときには全メンバを安全な値で初期化するべきです。

>>なぜですか?
行末の「,」までで1レコード分読み込みが終了しますが、ロジック上その直後にある「\n」によって次のレコードの先頭(countメンバ)に値が0のデータが挿入されるからです。

このようなデータに対応出来るようする為には、改行によってレコード分けされていることから
「,」=「項目の区切り」、「\n」=「レコードの区切り」と異なる意味を持つことを自覚します。
例えば改行コードを認識したらnext_recレコードフラグをセットしてif(num==7)の条件式をif(next_rec)などとし、そのifブロック内部でnext_recフラグをクリアするようにします。

余談ですが、new_enter_enemyとnow_enter_enemyという変数名は非常に紛らわしく不安定要素に感じました。

ひよこ

Re:敵データの読み込みについて

#11

投稿記事 by ひよこ » 15年前

サイト愛用者さんいろいろ提案ありがとうございます。
おっしゃる通りにしたら無駄なものがなくなりました。
次のレコードの先頭(countメンバ)に\0がはいってしまったってことですね。
わかりました。nonさん、サイト愛用者さんありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る