csvファイルから変数を読み込む事は可能でしょうか

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

csvファイルから変数を読み込む事は可能でしょうか

#1

投稿記事 by サンタクロース » 13年前

こんばんわ

ポーカーを作っている際に分からないことがあったので、質問させてください

僕はポーカーゲームの中にメッセージ画面を実装しようと考えています

そこでメッセージ文をcsvファイルを使って読み込もうと思っています

たとえば、csvファイルの2行1列目に「%sが親です」、2行2列目に「Name」と書かれていたとします

そこで質問なのですが、文字列定数"Name"でなく 文字列"Player"を格納したChar型の変数として読み込むにはどうしたら良いでしょうか。
別の言い方をすると、Message.elem1に文字列"Player"を渡してあげるにはどうすればよいでしょうか

蛇足ですが、elem1 ~ elem4という変数は説明をするために用意したものなので、char型変数を代入できないぞといった点は無視してください

コード:


char Name[80] = "Player";

typedef struct{
    char str[80];//メッセージ本文
    int elem1;//本文中の%s,や%dに入る変数
    int elem2;
    int elem3;
    int elem4;
}Message_t;

Message_t Message[100];

//csvファイルの読み込み
void file_load(){
	int i = -1;//ファイルの列
	int j;//ファイルの行
	int FileHandle;
	char filePath[80] ="../dat/dat.csv";
	char* tp;
	char String[256] = {'\0'};

	FileHandle = FileRead_open(filePath);

	//ファイルを読み込めなかったら
	if(FileHandle == NULL){
		printfDx("ファイル読み込みに失敗\n");
		return;
	}

	while(FileRead_eof(FileHandle) == 0){//ファイルの終端でなければ

		//ファイルを一行読み込む
    	FileRead_gets(String,256 , FileHandle);

		//最初の一行は読み飛ばす
		if(i == -1){
			i++;
			continue;
		}

		//最初の列は読み込まない
        tp = strtok(String,",/");

		j = 0;

		while(*tp != '/'){//一行の終端でなければ
			tp = strtok(NULL,",");

			switch(j){
			
			case 0:
				strcpy(Message[i].str , tp);//一列目のメッセージを読み込む(文字列「%sが親です」が入る)

				break;
			case 1:
				Message[i].elem1= atoi(tp);//ここに文字列"Player"が格納された変数Nameを渡したい
			    break;
			case 2:
				Message[i].elem2= atoi(tp);
			    break;
			case 3:
				Message[i].elem3 = atoi(tp);
				break;
			case 4:
				Message[i].elem4 = atoi(tp);
				break;
	
		
			default: break;
	       
			}
			j++;
		}
		i++;
	}

	FileRead_close(FileHandle);

	return;

}


アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: csvファイルから変数を読み込む事は可能でしょうか

#2

投稿記事 by softya(ソフト屋) » 13年前

今一歩入力データとか動作の意図が分からないので入力データのサンプル(数行あるもの)とMessage_tをどういう風に使いたいか書いてもらってよいでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

とっち
記事: 56
登録日時: 13年前
住所: 岡山

Re: csvファイルから変数を読み込む事は可能でしょうか

#3

投稿記事 by とっち » 13年前

こういうことでしょうか?(違っていたらごめんなさい)

コード:

#include "DxLib.h"

typedef struct{
	char data[256];
	char name[256];
}Data_t;

Data_t Load(){
	Data_t temp;
	int fp=FileRead_open("test.csv");
	char buf[256];
	char token[10][256];
	
	while(FileRead_eof(fp)==0){
		if(FileRead_gets(buf,256,fp)==-1)//1行読み込む
			continue;

		int n=0,s=0;
		for(int i=0;i<256;i++){
			if(buf[i]==','){
				token[n][s]='\0';
				s=0;
				n++;
				continue;
			}
			if(buf[i]=='\0'){
				token[n][s]='\0';
				n++;
				break;
			}
			token[n][s]=buf[i];
			s++;
		}

		// データ代入
		strcpy(temp.data,token[0]);
		strcpy(temp.name,token[1]);

	}

	FileRead_close(fp);
	return temp;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen( DX_SCREEN_BACK );
	
	Data_t input;
	input=Load();
	char data[256];
	sprintf(data,input.data,input.name);
	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){
		DrawString(0,0,data,GetColor(255,255,255));
	}

	DxLib_End();
	return 0;
}

// test.csv
プレーヤー:%s,自分
実行結果は
プレイヤー:自分

Load関数は僕用に変えていますが意味はありません。
WinMain関数のinput.dataには"プレーヤー:%s"、input.nameには"自分"が入っています。
それをsprintf関数でくっつけて、WinMain関数のdataに入れています。

サンタクロース
記事: 8
登録日時: 13年前

Re: csvファイルから変数を読み込む事は可能でしょうか

#4

投稿記事 by サンタクロース » 13年前

回答ありがとうございます。

>>とっちさん
説明不足だったですよね、すみません。
僕はその"自分"という文字列定数でなくて文字列変数を読み込みたいのです

>>softyaさん
入力データのサンプル、というのはcsvファイルのことでよいのでしょうか
ただ、csvファイルのアップロードの仕方が分からず、代わりに画像ファイルにしてアップロードしてみました

まず、僕の実装したい内容をソースコード中にそのまま書いた場合のソースコードを書いてみます

コード:


Player[0].Name = "Sum";
Player[1].Name = "Jon";
    ・
  ・
  ・
Player[最大値].Name = "Jonny";
   
Player[0].Zankin = 100;
Player[1].Zainkin = 200; 
 ・
 ・
 ・
Player[最大値].Zankin = 400;

//メッセージ一文の構造体
typedef struct{
    char temp[80];
    char str[80];//メッセージ本文
    int elem1;//本文中の%s,や%dに入る変数
    int elem2;
    int elem3;
    int elem4;
}Message_t;

//メッセージを完成させる
Message[0].temp = "%sが親です";
Message[0].elem1 = Player[2].Name;
sprintf(Message[0].str , Message[0].temp , Message[0].elem1);

Message[1].temp = "ゲームを開始します";
sprintf(Message[1].str, Message[1].temp);

Message[2].temp = "%sが親です";
Message[2].elem1 = Player[3].Name;
Message[2].elem2 = Player[3].Zankin;
sprintf(Message[2].str , Message[2].temp , Message[2].elem1 , Message[2].elem2);

   ・
   
   ・
   
   ・

Message[最大値].temp = ~~~
   ・
   ・
   ・

また、今回の問題点を除いて、仮のソースコードを書いていこうとしたところ、また別の問題点が浮上して手が進まなくなってしまったので、日本語でMessage_tの処理手順を進めていきます

1.csvファイルから「メッセージの本文」と「メッセージの本文を補完するための変数:パラメタ1~4」を入力します

コード:

   while(*tp != '/'){//一行の終端でなければ
            tp = strtok(NULL,",");
 
            switch(j){
            
            case 0:
                strcpy(Message[i].str , tp);//一列目のメッセージを読み込む(文字列「%sが親です」が入る)
 
                break;
            case 1:
                Message[i].elem1= atoi(tp);//ここに文字列"Player"が格納された変数Nameを渡したい
                break;
            case 2:
                Message[i].elem2= atoi(tp);
                break;
            case 3:
                Message[i].elem3 = atoi(tp);
                break;
            case 4:
                Message[i].elem4 = atoi(tp);
                break;
    
        
            default: break;
           
            }
            j++;

(ここでパラメタを用意する理由は、メッセージを表示するタイミングによって表示する内容が
違ってくるからです。
たとえば「〇〇が親」です、の〇〇の部分は定数として読み込むことが出来ません)

2.メッセージを表示する関数を呼び出します

 2.1.メッセージの本文にパラメタを渡すための関数を呼び出します

 2.2.なんらかのボタンが押されたらメッセージ画面を消します

大雑把ですが、手順をこのように定めてみました

まず質問が3つあります

質問一 1.の手順で、 Message.elem1 ~ Message.elem4に変数を渡すにはどうすれば良いでしょうか?
例えば、パラメタ1がPlayer[1].Nameの場合、格納されている文字列"Jon"をMessage.elem1に格納させたい

質問二 1.の手順で、Message.elem1 ~ 4に変数を渡すとき、文字列、整数、小数点を
渡したい場合があるので、どのように代入させてあげればよいのかが分かりません

質問三 質問二とも似ているのですが、2.1の手順でメッセージの本文にパラメタを渡すための関数を定義する際、仮引数の型をどのように定義してあげればいいか分かりません


この質問を書いているうちに自分でもよくわからなくなってきたので、質問の意図がうまく伝わらないかもしれないです(汗)

また、これを聞いては本末転倒なのですが、
「呼び出すたびに内容が変わるメッセージ」はソースコードに直接。
「いつ呼び出しても内容が変わらないようなメッセージ」はcsvファイルで読み込みと
分けてしまった方がいいのでしょうか?









画像

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: csvファイルから変数を読み込む事は可能でしょうか

#5

投稿記事 by softya(ソフト屋) » 13年前

csvを見ました。それはcsvから変数あるいは変数名を読み込むのではなくて指定されたプログラム内部にある変数の値をこの場所に表示して欲しいと言う仕様ですね。
外部から動的に変数名を指定するのは困難が付きまとうのでおすすめできません(無理やり面倒なことをすれば出来ない事は無いですが悪いプログラムです)。

やるとしたら抽象化します。
%PlayerName%の残額は%Zankin%です。
と言った感じでしょうか。%PlayerName%や%Zankin%の部分を対応する変数の値と置き換えます。文字列の置き換えですね。

[補足]
置き換える部分の文字列はC言語ならsprintfやC++ならsstreamなどで必要に応じて文字列変換して作成します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

サンタクロース
記事: 8
登録日時: 13年前

Re: csvファイルから変数を読み込む事は可能でしょうか

#6

投稿記事 by サンタクロース » 13年前

>>sofutyaさん

回答ありがとうございます。
変数を読み込むという書き方が悪かったですね、softyaさんの言うとおり読み込んだ文字列と同じプログラム内にある変数の値を置き換えたかったのですが、悪いプログラムだったんですね;

自分の勝手な妄想ですが、ドラクエや、ファイナルファンタジーなど、大規模なゲームで
メッセージを外部からロードを行わず、ソースコードに直接、一文一文初期化だなんてことはしないだろうと思って、エクセルからロードしようと思いました

でも、今回実際に使うメッセージは10 ~ 20 程度なので、とりあえずソースコードで直接初期化を行おうと思います。

閉鎖

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