ページ 11

CSV読み込みの手法

Posted: 2012年9月18日(火) 21:36
by FFPRG好き入門者
龍神プログラミングの館11章を参考にCSVファイルを参照して敵のパラメータをセットする関数を
作成しました。引数に敵のパラメータ構造体と敵のindex番号を指定すると対象の敵パラメータが読み込めれる関数を作成しようと思ったのですが、構造体のメンバをunsigned char にするパラメータによってはとゴミが入ります。とれるところはとれていおります。
(unsigned char)でキャストしても上手くいかず、メンバをint型にすると改善されます。
何が原因でしょうか?ご教示お願い致します。

以下がコードとなります。※「★」箇所になります。

コード:

void Load_Enemy_Param(Enemy_Param *enemy_order, int number)
{
	int fp, i;
	int n = 0;
	int num = 0;
	char* fname = "enemy/EnemyTable.csv";

	int input[256]={0,};
	char inputc[256] ={0,} ;

	fp = FileRead_open("enemy/EnemyTable.csv");//ファイル読み込み
    if(fp == NULL){
		printfDx("read error\n");
		return;
    }
    
    //出力対象の計算
    n = number + 1;
    for(i = 0; i < n; i++){//最初から対象行まで読み飛ばす
		while(FileRead_getc(fp)!='\n');
    }
    while(1){
		for(i=0;i<1024;i++){
			inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
            
            if(input[i]==',' ){//カンマ
                inputc[i]='\0';//そこまでを文字列とし
                break;
            }
            if(input[i]=='\n'){//改行ならなら
				goto EXFILE;//終了
            }
		}
        switch(num){
     //★以下が質問箇所
            case 0: enemy_order->no		    =atoi(inputc);break;
            case 1: enemy_order->name       =inputc;	  break;
            case 2: enemy_order->level      =atoi(inputc);break;
            case 3: enemy_order->hp         =atoi(inputc);break;
            case 4: enemy_order->mp         =atoi(inputc);break;
            case 5: enemy_order->pw         =atoi(inputc);break;
            case 6: enemy_order->dif        =atoi(inputc);break;
            case 7: enemy_order->sp         =atoi(inputc);break;
            case 8: enemy_order->mag        =atoi(inputc);break;
            case 9: enemy_order->soul       =atoi(inputc);break;
            case 10:enemy_order->eva        =atoi(inputc);break;
            case 11:enemy_order->mag_eva    =atoi(inputc);break;
            case 12:enemy_order->money      =atoi(inputc);break;
            case 13:enemy_order->exp        =atoi(inputc);break;
            case 14:enemy_order->com1       =atoi(inputc);break;
            case 15:enemy_order->com2       =atoi(inputc);break;
            case 16:enemy_order->com3       =atoi(inputc);break;
            case 17:enemy_order->com4       =atoi(inputc);break;
            case 18:enemy_order->com5       =atoi(inputc);break;
            case 19:enemy_order->raitem     =atoi(inputc);break;
            case 20:enemy_order->item       =atoi(inputc);break;
            case 21:enemy_order->stea_raitem=atoi(inputc);break;
            case 22:enemy_order->stea_item  =atoi(inputc);break;
            
        }
        num++;
    }
EXFILE:
    FileRead_close(fp);
}

//******************************************************************************
typedef struct{
    //★ intならゴミ入らず
	unsigned char no;
	char* name;
	unsigned char level;
	unsigned char hp;
	unsigned char mp;
	unsigned char pw;
	unsigned char dif;
	unsigned char sp;
	unsigned char mag;
	unsigned char soul;
	unsigned char eva;
	unsigned char mag_eva;
	unsigned int  money;
	unsigned int exp;
	unsigned char com1;
	unsigned char com2;
	unsigned char com3;
	unsigned char com4;
	unsigned char com5;
	unsigned char raitem;
	unsigned char item;
	unsigned char stea_raitem;
	unsigned char stea_item;
}Enemy_Param;

Re: CSV読み込みの手法

Posted: 2012年9月18日(火) 21:59
by box
FFPRG好き入門者 さんが書きました:構造体のメンバをunsigned char にするパラメータによってはとゴミが入ります。
「ゴミ」の定義を教えてください。

それはそうと、
FFPRG好き入門者 さんが書きました:

コード:

	int fp, i;
    if(fp == NULL){
int型の数値とポインターとを比べているのはなぜでしょうか。
FFPRG好き入門者 さんが書きました:

コード:

	int input[256]={0,};
	char inputc[256] ={0,} ;
		for(i=0;i<1024;i++){
			inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
配列の要素数とループの回数との間に矛盾があるように見えます。
大丈夫でしょうか。
FFPRG好き入門者 さんが書きました:

コード:

     //★以下が質問箇所
            case 0: enemy_order->no		    =atoi(inputc);break;
atoi()の結果というint型を、それよりサイズの小さい型にむりやり入れようとしているように見えます。
大丈夫でしょうか。

Re: CSV読み込みの手法

Posted: 2012年9月18日(火) 22:24
by FFPRG好き入門者
「ゴミ」の定義を教えてください。
→例えば [2]を期待しているパラメータに対して出力すると[2’|’]と出力され
 この[|]をゴミと表現しました。説明至らず申し訳ございません。
 [|]で出力されるものは他にもいろいろあるのですがどれもコピーして貼り付けると「''」となります。
 ※'¥0'が入っているものだと思いますがなんでこんな表現になるのかと思い質問させてもらいました。

int型の数値とポインターとを比べているのはなぜでしょうか。
→あまり意識しておりませんでした。龍神プログラミングの館11章にあったものをそのまま使ってしまってます。

配列の要素数とループの回数との間に矛盾があるように見えます。
大丈夫でしょうか。
→こちらは問題ありですね、修正します。

atoi()の結果というint型を、それよりサイズの小さい型にむりやり入れようとしているように見えます。
大丈夫でしょうか。

→仕様として0~255までの範囲しか入らないので問題かと思います。気持ち悪いかもしれませんが・・

Re: CSV読み込みの手法

Posted: 2012年9月18日(火) 22:39
by へにっくす
質問の答えではありませんが
気になったところだけ。

コード:

case 1: enemy_order->name       =inputc;      break;
char *であるname変数に、ローカル変数inputcをそのまま代入してはいけません
何故ならその後次の項目をセットするのにinputcを上書きしているため、
nameの中身も変わるからです。
Basicであれば、上記のやり方で文字列が保持されますが、
C/C++では自前で確保する必要があります。

コード:

// char *nameでなく、char name[1024];とする
case 1: strcpy(enemy_order->name, inputc); break;

Re: CSV読み込みの手法

Posted: 2012年9月18日(火) 23:06
by FFPRG好き入門者
へにっくす様
ご指摘ありがとうございます。
とても助かります!

Re: CSV読み込みの手法

Posted: 2012年9月19日(水) 00:00
by Ryo
→例えば [2]を期待しているパラメータに対して出力すると[2’|’]と出力され
と、ありますが、
出力するというのは、どこにどんなふうに出力していますか?

#単にnameの使い方が間違っていただけだったのかもしれませんが

Re: CSV読み込みの手法

Posted: 2012年9月19日(水) 20:41
by FFPRG好き入門者
Ryo さんが書きました:
→例えば [2]を期待しているパラメータに対して出力すると[2’|’]と出力され
と、ありますが、
出力するというのは、どこにどんなふうに出力していますか?

#単にnameの使い方が間違っていただけだったのかもしれませんが
デバックを実行して構造体の中身を確認しておりました。
出力という文言がわかりずらいですね、申し訳ありません。

Re: CSV読み込みの手法

Posted: 2012年9月19日(水) 21:33
by softya(ソフト屋)
char型なのでデバッガが親切に文字型としても表示しているだけって事はないですか?
数値の2だと文字が割り当てられていないので文字としては意味がありません。
数値が48だと文字の'0'で49なら'1'が表示されるはずです。

Re: CSV読み込みの手法

Posted: 2012年9月19日(水) 23:15
by FFPRG好き入門者
softya(ソフト屋) さんが書きました:char型なのでデバッガが親切に文字型としても表示しているだけって事はないですか?
数値の2だと文字が割り当てられていないので文字としては意味がありません。
数値が48だと文字の'0'で49なら'1'が表示されるはずです。
ご指摘の通りデバッガが親切に文字型としても表示しているようです。
実際DrawFormatStringを使用して確認してみると、値は取得できておりました。
数値が48だと文字の'0'
49なら'1'が表示されました。
ありがとうございます。