エラーでます。関数化

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

エラーでます。関数化

#1

投稿記事 by endo » 8年前

修正します
最後に編集したユーザー endo on 2015年11月15日(日) 21:10 [ 編集 1 回目 ]

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: エラーでます。関数化

#2

投稿記事 by みけCAT » 8年前

  • 4つの数字がランダム化できてません。
  • 入力もうまくできてないと思います。
  • 関数化
以外を修正してみました。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define NUM 4
#define LIMIT 10

int main(void)
{
	char number[LIMIT];
	char answer[NUM];
	char tmp,expect[LIMIT];
	int hit,brow;
	int input_count = 0; /* 入力回数を数える用 */
	int i,j;

	srand((unsigned int)time(NULL));
	
	for (i=0;i<10;i++) /* numberの初期化処理を追加 */
	{
		number[i] = i;
	}
	
	for (i=0;i<10;i++)
	{
		j = rand() % 10;
		tmp = number[i];
		number[i] = number[j];
		number[j] = tmp;
	}
	for (i = 0; i < NUM; i++) 
	{
		answer[i] = number[i] + '0'; /* 数値を文字に変換して保存 (0-9は連続していることが規格で保証されている) */
		printf("%c", answer[i]);
	}
	printf("4桁入力してください。\n");
	do
	{
		fgets(expect,10,stdin);
		if (++input_count >= LIMIT) /* 10回まで入力したら、エラー判定する */
		{
			printf("エラーが発生しました。\n");
			return 1;
		}
		hit=0;
		brow=0;
		
		for(i=0;i<NUM;i++)
		{
			for(j=0;j<NUM;j++)
			{
				if(expect[i]==answer[j])
				{
					if(i == j)
					{
						hit++;
					}
					else
					{
						brow++;
					}
				}
			}
		}
		printf("ヒット=%d ブロー=%d\n",hit,brow); /* dが抜けているので追加 */
		if (hit == NUM) /* 成功判定 */
		{
			printf("成功\n");
			break;
		}
	} while(1); /* while(条件);を追加 */
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

超初級者
記事: 56
登録日時: 9年前

Re: エラーでます。関数化

#3

投稿記事 by 超初級者 » 8年前

考え方の例。

4桁の数値ではなく、4桁の数字からなる文字列として考える。
まずはヒットについて考える。ここは関数化できるはず。
ヒットした場所は、数字以外の文字に変えておく。
こうしておくと、ブローのチェックの際にそこを無視できる。
次に、ブローについて考える。ここも関数化できるはず。
以上の処理を、4桁ともヒットするまで、最大10回繰り返す。

endo
記事: 3
登録日時: 8年前

Re: エラーでます。関数化

#4

投稿記事 by endo » 8年前

ありがとうございます。Whileって何のための処理なんですか?
最後のループ処理の判定が必要だったんですね。

関数は処理と出力にすればいいですかね?

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: エラーでます。関数化

#5

投稿記事 by みけCAT » 8年前

endo さんが書きました:Whileって何のための処理なんですか?
入力と判定を繰り返すための処理でしょう。
endo さんが書きました:関数は処理と出力にすればいいですかね?
全部が処理なので、「処理にすればいい」というのはナンセンスでしょう。
  • 答えの生成
  • ヒットとブローの判定
を別関数にするとよさそうだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: エラーでます。関数化

#6

投稿記事 by box » 8年前

質問者さんが隠れてしまったので、私も隠れます。
最後に編集したユーザー box on 2015年11月15日(日) 21:58 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

endo
記事: 3
登録日時: 8年前

Re: エラーでます。関数化

#7

投稿記事 by endo » 8年前

修正します
最後に編集したユーザー endo on 2015年11月15日(日) 21:09 [ 編集 1 回目 ]

box
記事: 2002
登録日時: 13年前

Re: エラーでます。関数化

#8

投稿記事 by box » 8年前

質問者さんが隠れてしまったので、私も隠れます。
最後に編集したユーザー box on 2015年11月15日(日) 21:58 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

hoge

Re: エラーでます。関数化

#9

投稿記事 by hoge » 8年前

マルチポストをするのでしたら、フォーラムルールにあるように相互リンクしましょう。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=77667

box
記事: 2002
登録日時: 13年前

Re: エラーでます。関数化

#10

投稿記事 by box » 8年前

質問者さんがコードを隠してしまったので、私も隠します。
最後に編集したユーザー box on 2015年11月15日(日) 21:56 [ 編集 1 回目 ]
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: エラーでます。関数化

#11

投稿記事 by みけCAT » 8年前

endo さんが書きました:修正します
endo さんが書きました:修正します
記事を勝手に削除してはいけません。
「修正します」と宣言したのであれば、削除ではなく修正をしてください。
「修正」される前の記事
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

よもやま

Re: エラーでます。関数化

#12

投稿記事 by よもやま » 8年前

endo さんが書きました:修正します
関数化にあたっては、
http://bbs.wankuma.com/index.cgi?mode=al2&namber=77667
にて投稿されたコードを元にしています。
参考にしていただければ幸いに存じます。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#include <memory.h>
#include <string.h>

#define NUM 4
#define LIMIT 10

/* doxygen comment style
 * must option settings: 
 * JAVADOC_AUTOBRIEF yes
 */

/**
 * Hit数,Brow数結果格納構造体
 */
typedef struct  {
	
	int hit;	/**< ヒット数. */
	int brow;	/**< ブロウ数. */
	int isAllHit;	/**< 全てヒットしたか(0==ヒットしていない 0!=全てでヒット. */
}HitBrowResult;

/**
 * Hit数,Brow数結果格納構造体初期化
 * @param target 初期化の対象となるHit数,Brow数結果格納構造体
 */
void initialize_Result(HitBrowResult *target)
{
	target->hit = 0;
	target->brow = 0;
	target->isAllHit = 0;
}

/** 
 * 答え合わせ
 * (想定)initialize_Result関数にて構造体内は初期化済みである
 * @param checkSource 答え合わせ対象
 * @param answer 答え
 * @param inputLen 答え合わせ対象の文字数
 * @param answersize 答えサイズ
 * @param target 答え合わせ結果格納先
 */
void answerCheck(const char checkSource[], const char answer[], const int inputLen, const int answersize, HitBrowResult *target)
{
	if (inputLen < 1)
	{
		/* 入力文字数が1文字に満たない場合は、チェックしない */
		return;
	}
	/* 比較する */
	int looplimit = 0;
	int i;

	looplimit = answersize;
	if (inputLen < looplimit)
	{
		looplimit = inputLen;
	}
	for (i = 0; i < looplimit; i++)
	{
		if (answer[i] == checkSource[i])
		{
			target->hit++;
		}
		else
		{
			target->brow++;
		}
	}
	if ((target->hit + target->brow) < answersize)
	{
		target->brow = target->brow + (answersize - target->hit);
	}

	if (answersize == target->hit)
	{
		target->isAllHit = 1;
	}
}

/**
 * 答え表示
 * @param answer 答え
 * @param answersize 答えサイズ
 */
void answerView(const char answer[], const int answersize)
{
	int i;
	printf("正解は");
	for (i = 0; i < answersize; i++)
	{
		printf("%c", answer[i]);
	}
	printf("\n");
}

/** 
 * 結果表示(Hit数,Brow数結果格納構造体)
 * @param target 答え合わせ結果格納先
 */
void view_Result(HitBrowResult target)
{
	printf("ヒット=%d ブロー=%d\n", target.hit, target.brow);
	if (0 != target.isAllHit)
	{
		printf("おめでとう\n");
	}
}

/**
 * 数字(文字)入力
 * (想定)
 *	maxsizeはdefine定数"LIMIT"以上の値とならないこと
 *	(tmpBufferをdefine定数"LIMIT"に依存させないのであればmallocやfreeを使いましょう。)
 * @param target 入力文字/文字列格納先(改行"\n"はふくまない)
 * @param maxsize 格納サイズ
 */
int getNumbersFromStdIn(char target[], const int maxsize)
{
	char tmpBuffer[LIMIT+1];
	int i, j;
	int inputLength;

	memset(tmpBuffer, (int)NULL, sizeof(tmpBuffer) / sizeof(tmpBuffer[0]) );
	memset(target, (int)NULL, maxsize);

	printf("4桁入力してください。(重複しない)\n");
	fgets(tmpBuffer, maxsize, stdin);

	/* 改行(\n)を除き、入力された文字をCopy
	  strncpyやmemcpyとか置き換えができそう。。
	 「(重複しない)」が気になりつつもベタッと実装。
	 */
	inputLength = strlen(tmpBuffer) - 1;
	for (i = 0, j = 0; i < maxsize; i++, j++)
	{
		if (j < inputLength)
		{
			target[i] = tmpBuffer[i];
		}
	}
	return j;
}

/**
 * Hit, Brow処理メイン
 */
int main(void)
{
	char number[LIMIT];
	char answer[NUM];
	char tmp, expect[LIMIT];
	HitBrowResult resultStore;
	int count = 0;
	int i, j;
	int inputLen = 0;

	srand((unsigned int)time(NULL));

	/* 配列の初期化処理*/
	for (i = 0; i < LIMIT; i++)
	{
		number[i] = i;
	}
	for (i = 0; i < LIMIT; i++)
	{
		j = rand() % 10;
		tmp = number[i];
		number[i] = number[j];
		number[j] = tmp;
	}
	for (i = 0; i < NUM; i++)
	{
		/*数値を文字に変換*/
		answer[i] = number[i] + '0';
	}

	do 
	{
		/* Hit数などの結果格納先を初期化 */
		initialize_Result(&resultStore);

		/* 標準入力から入力を得る */
		inputLen = getNumbersFromStdIn(expect, (sizeof(expect) / sizeof(expect[0])));

		/* 答え合わせ */
		answerCheck(expect, answer, inputLen, (sizeof(answer) / sizeof(answer[0])), &resultStore);

		/* 結果表示 */
		view_Result(resultStore);
		if (0 != resultStore.isAllHit)
		{
			/* あらかじめ用意していた答えとすべて一致した場合
				メインループから抜けてプログラム終了
			 */
			break;
		}

		count++;
		if (LIMIT <= count) 
		{
			/*	10回入力してあらかじめ用意していた答えと一致しない場合、
				・答えを表示
				・メインループから抜けてプログラム終了
			 */
			answerView(answer, (sizeof(answer) / sizeof(answer[0])));
			break;
		}
	} while (1);

	/* 後始末 */
	printf("\n");
	printf("ゲームオーバー\n");

	return 0;
}


閉鎖

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