MENU

【C言語】クイズゲーム作成(4)構造体登録関数でスッキリ

クイズゲーム作成(4)構造体登録関数でスッキリ

こんにちは、コン(@pippi_kon)です。

この記事では『C言語でのクイズゲームの作り方』をご紹介しています。

前回は、構造体を使用してプログラムを見やすくする方法をご紹介しました。

変数名(構造体のメンバー名)に意味を持たせることができ、可読性がアップしました。

しかし、構造体に登録する処理、具体的には「strncpy関数の発行」が多くなってしまい、その点ではプログラムが少々見づらくなってしまいました。

なので今回は、構造体にデータを登録する関数を作成して可読性をアップさせます。

OS:Windows 10(x64)
開発環境:Visual Studio 2019(Community)

目次

今回の目標

今回作成するプログラムの出力結果です。

クイズゲーム04_今回の目標

出力結果自体は前回と変わりませんが、中身のプログラム処理が変わります

問題文の「リンゴは英語で何と言う?」や選択肢の「apple」などを、メイン関数内で愚直に構造体に登録するのではなく、関数で行うように変更しています。

▲目次へ戻る

プログラム全文

今回作成したプログラムのご紹介です。

のちほど、プログラムの解説を行います。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>

typedef struct {
	char	mondai[100];
	char	sentaku[3][100];
	int		answer_no;
}quiz_t;

void set_quiz(quiz_t* t, char* m, char* s1, char* s2, char* s3, int a)
{
	strncpy(t->mondai, m, sizeof(t->mondai));
	strncpy(t->sentaku[0], s1, sizeof(t->sentaku[0]));
	strncpy(t->sentaku[1], s2, sizeof(t->sentaku[1]));
	strncpy(t->sentaku[2], s3, sizeof(t->sentaku[2]));
	t->answer_no = a;
}

int main(void)
{
	int		ans;
	int		i;
	quiz_t	quiz[3];

	set_quiz(&quiz[0], "リンゴは英語で何と言う?", "apple", "orange", "banana", 1);
	set_quiz(&quiz[1], "大正->昭和->○○->令和\n○○に入る年号は?", "慶応", "明治", "平成", 3);
	set_quiz(&quiz[2], "世界三大珍味はどれ?", "イカスミ", "キャビア", "チーズ", 2);

	for (i = 0; i < 3; i++) {
		printf("[第%d問]\n", i + 1);
		printf("%s\n", quiz[i].mondai);
		printf("1:%s  2:%s  3:%s\n", quiz[i].sentaku[0], quiz[i].sentaku[1], quiz[i].sentaku[2]);
		printf(">>> ");
		scanf("%d", &ans);
		if (ans == quiz[i].answer_no) {
			printf("正解!\n\n");
		}
		else {
			printf("不正解...\n");
			printf("正解は %d:%s です。\n\n", quiz[i].answer_no, quiz[i].sentaku[quiz[i].answer_no - 1]);
		}
	}

	return 0;
}

▲目次へ戻る

スポンサーリンク

プログラムの解説

構造体登録関数の作成

void set_quiz(quiz_t* t, char* m, char* s1, char* s2, char* s3, int a)
{
	strncpy(t->mondai, m, sizeof(t->mondai));
	strncpy(t->sentaku[0], s1, sizeof(t->sentaku[0]));
	strncpy(t->sentaku[1], s2, sizeof(t->sentaku[1]));
	strncpy(t->sentaku[2], s3, sizeof(t->sentaku[2]));
	t->answer_no = a;
}

構造体の各メンバーにデータを設定する関数「set_quiz」を作成しました。

引数の意味は以下の通り。

引数意味
quiz_t* tデータ設定する構造体
char* m問題文
char* s1選択肢1
char* s2選択肢2
char* s3選択肢3
int a答えの番号

第1引数「quiz_t* t」で指定した構造体に、第2~6引数で指定した値を設定します。

前回と同様に、問題文・選択肢はstrncpy関数を使用し、答えの番号は直接代入しますが、構造体メンバーの指定方法が異なります

前回は『quiz[0].mondai』のように構造体名とメンバー名を「.(ドット)」でつなげていました。

これは、メイン関数にある構造体の実体をそのまま参照していたため。

構造体の実体は以下の箇所で宣言しています。

	quiz_t	quiz[3];

しかし、今回はメイン関数ではなくサブ関数(set_quiz)から構造体を参照することになります。

サブ関数に実体を渡して、データ設定して、実体をメイン関数に返す、という方法もありますが、処理がちょっと複雑になってしまいます。

そのため、実体ではなく構造体の場所(アドレス)を渡し、サブ関数から直接構造体にデータ設定します

アドレス参照する際は、『t->mondai』のようにドットではなく矢印(->)でつなげます。

▲目次へ戻る

構造体登録関数の呼び出し

	set_quiz(&quiz[0], "リンゴは英語で何と言う?", "apple", "orange", "banana", 1);
	set_quiz(&quiz[1], "大正->昭和->○○->令和\n○○に入る年号は?", "慶応", "明治", "平成", 3);
	set_quiz(&quiz[2], "世界三大珍味はどれ?", "イカスミ", "キャビア", "チーズ", 2);

作成した関数を使用して構造体にデータを登録します。

一つ目の構造体(quiz[0])に登録するときの引数の値は以下の通り。

引数
quiz_t* t&quiz[0]
char* m"リンゴは英語で何と言う?"
char* s1"apple"
char* s2"orange"
char* s3"banana"
int a1

ここで重要なのが第一引数の指定方法です。

第一引数にはデータを設定する構造体を指定しますが、そのまま指定するのではなく、「&」を付けてアドレス参照形式で指定します。

▲目次へ戻る

スポンサーリンク

次回

▲目次へ戻る

created by Rinker
¥2,750 (2024/04/16 20:08:35時点 Amazon調べ-詳細)
created by Rinker
¥2,530 (2024/04/16 21:54:32時点 Amazon調べ-詳細)
  • URLをコピーしました!