ステータス異常のマークをつけるC言語関数を作りたいのですが

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

ステータス異常のマークをつけるC言語関数を作りたいのですが

#1

投稿記事 by 初心者 » 16年前

やりたい事は、例えば
Aさん[毒][麻痺]
Bさん[気絶][混乱][猛毒]
のように[/url]で囲まれたステータス異常をPOPして、ターン数内の場合表示を加えるという事です。
例えば、麻痺。効果ターン3とかにして、毎ターンに1ずつ減らし、ゼロになったら効果を説くやり方です。
二次配列を使いますstatsijou[kaz[/url][shousai]のようにしてkazuはステータス異常の列、shousaiは異常名と効果ターンです。
二次配列にダブり効果なし、ターン数が切れたら異常名をなしにすると言った感じです。
statsijou[0][0] = 毒, statsijou[0][1] = 3みたいな感じで
どのようにやるか分かる方いますか?ご教授お願いします。

SooA

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#2

投稿記事 by SooA » 16年前

0 でステ異常無し、0 以外ターン数で表せます。

毒  2
猛毒 0
麻痺 0
混乱 1
気絶 0

文字列は strcat() を使えば"追加"することができます。
\0 文字で初期化した文字列に
毒、猛毒、麻痺と順番にチェックしてターン数が
0 以外の場合に対応する文字列を追加していく。

初心者

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#3

投稿記事 by 初心者 » 16年前

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <SIOUX.h>

char *statsijou[128][128] = {
{"毒"},
{"猛毒"},
{"麻痺"},
{"混乱"},
{"気絶"},
};
char temp[128];

char *statsP[128][128] = {
{"毒"}, {"麻痺"},
};

void main()
{
int n, m;
char* l;
SIOUXSettings.fontid = 16400;
printf("%s\n", statsijou[0][0]);
printf("%s\n", statsijou[1][0]);
statsijou[0][1] = malloc(4);
strcpy(statsijou[0][1], "2");
statsijou[2][1] = malloc(4);
strcpy(statsijou[2][1], "3");

while(statsijou[0][0] != NULL){
printf("Aさん");
for(n = 0;statsijou[n][0] !=NULL;n++){
m = atoi(statsijou[n][1]);
if(m > 0) printf("[%s, %d]", statsijou[n][0], m);
m = m-1;
l = malloc(4);
sprintf(l, "%d", m);
strcpy(statsijou[n][1], l);
}
scanf("%s");

}
}

ここまで出来ました。この状態から、たとえば、scanfで「毒 3」と入力すると、statsijouの文字の中から、毒を選び、
効果ターン数を3に決定するには、どうすればいいのでしょうか?
あと、strcatの仕様が良く分からないのですが・・・どうか教えてください。

バグ

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#4

投稿記事 by バグ » 16年前

>>scanfで「毒 3」と入力すると…

これは、スペースで区切っているという事ですか?

strcat関数は、第一引数の指す文字列の末尾へ、第二引数の指す文字列をコピーするというものです。
#include <stdio.h>
#include <string.h>

int main()
{
	char sz[256] = {0};

	// char型配列のszに"じゃんけん"という文字列をコピーする
	strcpy(sz, "じゃんけん");
	printf("%s\n", sz);

	// szの指す文字列の末尾へ、"グー!!"という文字列をコピーする
	strcat(sz, "グー!!");
	printf("%s\n", sz);

	return 0;
}

初心者

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#5

投稿記事 by 初心者 » 16年前

そうです。今新しいの作りましたが、思うように動いてくれません。クラッシュしてしまいます。
strcpy(kata, temp);
for(atai = kata;*kata != '\0';kata++){
for(n = 0;*kata != ' ' && n < 10;) {n++;kata++;}
if(*kata == ' ') {*kata = '\0';
strncpy(namae, atai, n);*(namae+n) = '\0';
kata++;
}
}
atai = kata;


if(*kata == '\0') {strncpy(temp, atai, n);turn = atof(temp);
}//問題
//ステータス異常識別
m = 0;
printf("namae %s turn %g", namae, turna);
for(n = 0; n < 5;n++) {
pw = strcmp(statsijou[n][0], namae);
if(pw == 0) {
k = turn;
l = malloc(4);
sprintf(l, "%d", k);
strcpy(statsijou[n][1], l);
m++;
n=-1;
scanf("%s");
}
}

scanf("%s");
strcatの仕様は分かりましたありがとうございます。
このプログラムはポインターを移動して、「毒 3」の用にスペースで区切りポインターを移動して、スペースを検索し、
分割して変数に入れるというものなんですけど。

バグ

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#6

投稿記事 by バグ » 16年前

scanf関数は文字列内にスペースを見つけたら来たら、処理を終了するんじゃなかったかと…
カンマとかで区切った方がいいんじゃないかな?

SooA

Re:ステータス異常のマークをつけるC言語関数を作りたいのですが

#7

投稿記事 by SooA » 16年前

ソースプログラムを貼る場合は、
規約を読んで<pre>ソース</pre>タグで囲んでください。
(<>は半角)

入力に関して、ゲーム中にステータスと異常ターンを
入力することは無いので今は書きません。
今回はソース中で用意したデータを使います。
#include "stdio.h"
#include "strings.h"

int main()
{
	// ステータス名
	char status_name[5][6] = { "毒[", "猛毒[", "麻痺[", "混乱[", "気絶[" } ;
	// 表示用
	char sta[17] ;
	char pram[256] ;

	// 状態管理変数   通常時 0 、0 以外でターン数
	int  status[5] = { 1, 0, 2, 0, 0 } ; // 毒、猛毒、麻痺、混乱、気絶

	pram[0] = '\0' ;
	for( int i=0; i<5; i++ )
		if( status != 0 )
		{
			// ステータス名を追加
			strcat( pram, status_name ) ;
			// ターン数を文字列に変換
			itoa( status, sta, 10 ) ;
			// ターン数を追加
			strcat( pram, sta ) ;
			strcat( pram, "] " ) ;
		}

	// 結果表示
	printf( "Aさんの状態\n" ) ;	
	printf( "%s", pram ) ;	

	return 0 ;
}

※ = が抜けてたりしてたので修正と追加を行いました。

初心者

ありがとうございます出来ました。

#8

投稿記事 by 初心者 » 16年前

指摘されたところを直し、ソースを参考にしたら見事に出来ました。
なにか、簡略化できるようでしたら教えて下さい。ソースです。
「毒,4」などと入力すると読み込める仕様になりました。ご指摘通り、スペースだと出来ませんでした。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>
#include <string.h>
#include <SIOUX.h>

char *statsijou[128][128] = {
	{"毒"}, 
			{"猛毒"},
			{"麻痺"}, 
			{"混乱"}, 
			{"気絶"},
};
char temp[128];
char *kata, *atai;

char *statsP[128][128] = {
	{"毒", "3"}, {"麻痺", "4"},
};

void main()
{
	int n, m, pw, k;
	char* l;
	char *namae;
	double turn;
	SIOUXSettings.fontid = 16400;
	printf("%s\n", statsijou[0][0]);
	printf("%s\n", statsijou[1][0]);
	statsijou[0][1] = malloc(4);
	strcpy(statsijou[0][1], "2");
	statsijou[2][1] = malloc(4);
	strcpy(statsijou[2][1], "3");
	
	while(1){
	printf("Aさん");
		for(n = 0;statsijou[n][0] !=NULL;n++){
			m = atoi(statsijou[n][1]);
			if(m > 0) printf("[%s, %d]", statsijou[n][0], m);
			m--;
			l = malloc(4);
			sprintf(l, "%d", m);
			strcpy(statsijou[n][1], l);
		}
		scanf("%s", temp);
		pw = strcmp(temp, "def");
		if(pw == 0) {
			for(n = 0, m = 0; n < 5;n++) {
				pw = strcmp(statsijou[n][0], statsP[m][0]);
			if(pw == 0) {
				k = atoi(statsP[m][1]);
				l = malloc(4);
				sprintf(l, "%d", k);
				strcpy(statsijou[n][1], l);
					m++;
					n=-1;
				}
			}
		}
		
		//ステータス異常入力認識
		kata = malloc(10);
		strcpy(kata, temp);
		atai = temp;
		for(kata = temp;*kata != ',' && *kata != '\0' && n < 10; kata++) {n++;
		}
		namae = malloc(10);
		*kata = '\0'; strncpy(namae, temp, n);
		*(namae + n) = '\0';kata++;
		atai = kata;
		for(;*kata != '\0';kata++){
			n++;
		}
		if(*kata == '\0') {*kata = '\0';strncpy(temp, atai, n);*(temp + n) = '\0';turn = atoi(temp);
		}
		//ステータス異常識別
		m = 0;
		for(n = 0; n < 5;n++) {
				pw = strcmp(statsijou[n][0], namae);
			if(pw == 0) {
				k = turn;
				l = malloc(4);
				sprintf(l, "%d", k);
				strcpy(statsijou[n][1], l);
			}
			m++;
		}
	}
}

SooA

Re:ありがとうございます出来ました。

#9

投稿記事 by SooA » 16年前

>ソースを参考にしたら見事に出来ました。

問題点を挙げておきます。

malloc が多用されていますが一度も開放されていません。


if(*kata == '\0')
↑こういった文字列のつもりで比較させることはできません。
エラーは出なくても結果は正しくありません。
文字列を比較させたい場合は strcmp を使用します。
if( strcmp( kata, "\0" ) == 0 )


最初にも書きましたが、ターン数を文字列で管理するのは
お勧めできません、ターンが進むたびに文字列を解析して
-1 するはめになります。

閉鎖

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