龍神録11章の質問

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Fimbul
記事: 100
登録日時: 14年前

龍神録11章の質問

#1

投稿記事 by Fimbul » 13年前

コード:

//敵の出現情報をエクセルから読み込んで格納する関数
void load_story(){
        int n,num,i,fp;
        char fname[32]={"../dat/csv/storyH0.csv"};
        int input[64];
        char inputc[64];

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

        n=0 , num=0;
        while(1){
                for(i=0;i<64;i++){
                        inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
                        if(inputc[i]=='/'){//スラッシュがあれば
                                while(FileRead_getc(fp)!='\n');//改行までループ
                                i=-1;//カウンタを最初に戻して
                                continue;
                        }
                        if(input[i]==',' || input[i]=='\n'){//カンマか改行なら
                                inputc[i]='\0';//そこまでを文字列とし
                                break;
                        }
                        if(input[i]==EOF){//ファイルの終わりなら
                                goto EXFILE;//終了
                        }
                }
                switch(num){
                        case 0: enemy_order[n].cnt      =atoi(inputc);break;
                        case 1: enemy_order[n].pattern  =atoi(inputc);break;
                        case 2: enemy_order[n].knd      =atoi(inputc);break;
                        case 3: enemy_order[n].x        =atof(inputc);break;
                        case 4: enemy_order[n].y        =atof(inputc);break;
                        case 5: enemy_order[n].sp       =atof(inputc);break;
                        case 6: enemy_order[n].bltime   =atoi(inputc);break;
                        case 7: enemy_order[n].blknd    =atoi(inputc);break;
                        case 8: enemy_order[n].col      =atoi(inputc);break;
                        case 9: enemy_order[n].hp       =atoi(inputc);break;
                        case 10:enemy_order[n].blknd2   =atoi(inputc);break;
                        case 11:enemy_order[n].wait     =atoi(inputc);break;
                        case 12:enemy_order[n].item_n[0]=atoi(inputc);break;
                        case 13:enemy_order[n].item_n[1]=atoi(inputc);break;
                        case 14:enemy_order[n].item_n[2]=atoi(inputc);break;
                        case 15:enemy_order[n].item_n[3]=atoi(inputc);break;
                        case 16:enemy_order[n].item_n[4]=atoi(inputc);break;
                        case 17:enemy_order[n].item_n[5]=atoi(inputc);break;
                }
                num++;
                if(num==18){
                        num=0;
                        n++;
                }
        }
EXFILE:
        FileRead_close(fp);
}
エクセルを使って敵の出現データを作ってみよう
http://dixq.net/rp/11.html

龍神録の質問です。
エクセルから敵のデータを読み込む処理ですが、読み込んだデータをinputcとinputの2つに代入し、'/'の判定にinputcを、',' '\n' EOFの判定にinputを用いているのは何故でしょうか。
ページには理解しなくてもよいとあったのですが気になったので質問しました。
ご教示お願いします。
最後に編集したユーザー Fimbul on 2011年11月25日(金) 09:37 [ 編集 1 回目 ]

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: 龍神録11章の質問

#2

投稿記事 by beatle » 13年前

'/'の判定にinputcを、',' '\n' の判定にinputを用いている理由は、僕もよくわかりませんでした。
','と'\n'も普通の文字ですから、inputcと比較しても問題ないと思います。
ただし、EOFとchar型変数を比較するのはよく有りませんから、EOFと(int型である)inputを比較するのは理にかなっています。
EOF判定をするだけですから、inputは特に配列にする必要ななく、単にint型の変数1つで事足りると思います。
参考:C言語でEOFをchar型で比較してまずいのはなぜ?

Fimbul
記事: 100
登録日時: 14年前

Re: 龍神録11章の質問

#3

投稿記事 by Fimbul » 13年前

コードの書き間違いなのでしょうか。
EOFは参考を見たところ納得できました。

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: 龍神録11章の質問

#4

投稿記事 by beatle » 13年前

コード:

//敵の出現情報をエクセルから読み込んで格納する関数
void load_story() {
        int n, num, i, fp;
        const char* fname = "../dat/csv/storyH0.csv";
        int c;
        char input[64];

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

        n = 0;
        num = 0;
        while (1) {
                i = 0;
                while (i < sizeof(input) - 1) {
                        c = FileRead_getc(fp); //1文字取得する
                        if (c == '/') { //スラッシュがあれば
                                while (FileRead_getc(fp) != '\n'); //改行までループ
                        } else if (c == ',' || c == '\n') { //カンマか改行なら
                                break;
                        } else if (c == EOF) { //ファイルの終わりなら
                                goto EXFILE; //終了
                        } else {
                                input[i] = c;
                                i++;
                        }
                }
                input[i] = '\0';
                switch (num) {
                        case 0:  enemy_order[n].cnt       = atoi(input); break;
                        case 1:  enemy_order[n].pattern   = atoi(input); break;
                        case 2:  enemy_order[n].knd       = atoi(input); break;
                        case 3:  enemy_order[n].x         = atof(input); break;
                        case 4:  enemy_order[n].y         = atof(input); break;
                        case 5:  enemy_order[n].sp        = atof(input); break;
                        case 6:  enemy_order[n].bltime    = atoi(input); break;
                        case 7:  enemy_order[n].blknd     = atoi(input); break;
                        case 8:  enemy_order[n].col       = atoi(input); break;
                        case 9:  enemy_order[n].hp        = atoi(input); break;
                        case 10: enemy_order[n].blknd2    = atoi(input); break;
                        case 11: enemy_order[n].wait      = atoi(input); break;
                        case 12: enemy_order[n].item_n[0] = atoi(input); break;
                        case 13: enemy_order[n].item_n[1] = atoi(input); break;
                        case 14: enemy_order[n].item_n[2] = atoi(input); break;
                        case 15: enemy_order[n].item_n[3] = atoi(input); break;
                        case 16: enemy_order[n].item_n[4] = atoi(input); break;
                        case 17: enemy_order[n].item_n[5] = atoi(input); break;
                }
                num++;
                if (num == 18) {
                        num = 0;
                        n++;
                }
        }
EXFILE:
        FileRead_close(fp);
}
僕なりに改良してみました。参考にどうぞ。
(ただし、コンパイルさえしてないので悪しからず。もし試してみたら結果を教えてくださると嬉しいです。)

アバター
Dixq (管理人)
管理人
記事: 1662
登録日時: 14年前
住所: 北海道札幌市
連絡を取る:

Re: 龍神録11章の質問

#5

投稿記事 by Dixq (管理人) » 13年前

私も私なりに改良してみました。
あのコードは今は昔・・。
なんだかもうごめんなさいという感じです。
以下も綺麗なコードではありませんが、館にあって支障ないコードとして以下のように書いてみました。
よろしければどうぞ。

コード:

// 1行飛ばす
int SkipOneLine( int FileHdl ){
	int Ch;
	while( 1 ){
		Ch = FileRead_getc( FileHdl );
		if( Ch == -1 ){
			return -1;
		}
		if( Ch == '\n' ){
			return 0;
		}
	}
	return -1;
}

//敵の出現情報をエクセルから読み込んで格納する関数
void load_story(){

	int  FileHdl;//ファイルハンドル
	FileHdl = FileRead_open( "../dat/csv/11章/storyH0.csv" );//ファイル読み込み
	if( FileHdl == 0 ){	//読めなかったらエラー
		printfDx("read error\n");
		return;
	}

	SkipOneLine( FileHdl ) ;	//最初の二行は飛ばす
	SkipOneLine( FileHdl ) ;

	int n=0;
	int InputChar;	//一文字格納する入れ物
	int ScannedNum;		//スキャンできた個数
	while( 1 ){
		InputChar = FileRead_getc( FileHdl );//1文字取得する
		if( InputChar == '/' ){	//スラッシュがあれば
			SkipOneLine( FileHdl ) ;//一行読み飛ばし
			continue;
		} else {				//スラッシュじゃなければ
			FileRead_seek( FileHdl, -1, SEEK_CUR ) ;//さっき読んだ一文字戻す
		}
		//書式指定に応じて一行分読み込み
		ScannedNum = FileRead_scanf( 
			FileHdl,
			"%d,%d,%d,%lf,%lf,%lf,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
			&enemy_order[n].cnt,
			&enemy_order[n].pattern,
			&enemy_order[n].knd,
			&enemy_order[n].x,
			&enemy_order[n].y,
			&enemy_order[n].sp,
			&enemy_order[n].bltime,
			&enemy_order[n].blknd,
			&enemy_order[n].col,
			&enemy_order[n].hp,
			&enemy_order[n].blknd2,
			&enemy_order[n].wait,
			&enemy_order[n].item_n[0],
			&enemy_order[n].item_n[1],
			&enemy_order[n].item_n[2],
			&enemy_order[n].item_n[3],
			&enemy_order[n].item_n[4],
			&enemy_order[n].item_n[5]
		);
		if( ScannedNum != 18 ){	//18個全部読めなかったら処理を抜ける
			break;
		}
		n++;
	}
	FileRead_close( FileHdl );
}


Fimbul
記事: 100
登録日時: 14年前

Re: 龍神録11章の質問

#6

投稿記事 by Fimbul » 13年前

beatleさんのコードを試してみたところ、正常に動作している様です。
まさか、Dixqさん直々にコードを提供してもらえるとは驚きです。
私から見れば新しく書いて下さったコードは綺麗だと思うのですが、これでも綺麗でないと言うのはやはりプロの方はすごいのですね。
Dixqさんのコードを使わせてもらいます。

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

閉鎖

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