ページ 11

配列での文字列の扱いについて

Posted: 2022年12月06日(火) 16:59
by fukeroku
1問20点のクイズを5問出題し、得点を表示した後に回答の履歴を正不と一緒に表示するプログラムを作っているのですが、回答履歴の文字列の先頭にフフフフフフフフ.....というものが大量に出てしまいます。それと同時に、「Run-Time Check Failure #2 - Stack around the variable 'defo2' was corrupted.」というエラーも吐いています。メモリがオーバーフローしているのはなんとなくわかりますが、どこを直せばいいのかわかりません。以下、ソースコードです

コード:

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

char checkanswer(char ans[], char defo[], char log[])
{
	int result = strcmp(ans, defo);

	if (result == 0)
	{
		printf("正解です\n");
		strcat(log, ":○ ");
	}
	else
	{
		printf("不正解です\n");
		strcat(log, ":× ");
	}

	return result;
}
int main(void) {
	int sum = 0;
	char ans[100];
	char log[200];

	printf("問1:日本の首都は?\n");
	scanf("%s", &ans);
	char defo1[] = "東京";
	
	if (checkanswer(ans, defo1, log) == 0)
		sum += 20;

	printf("問2:日本で一番高い山は?\n");
	scanf("%s", &ans);
	char defo2[] = "富士山";
	strcat(log, defo2);
	if (checkanswer(ans, defo2, log) == 0)
		sum += 20;

	printf("問3:2022年に公開された新海誠が監督した映画は?\n");
	scanf("%s", &ans);
	char defo3[] = "すずめの戸締り";
	strcat(log, defo3);
	if (checkanswer(ans, defo3, log) == 0)
		sum += 20;

	printf("問4:マリオの弟は?\n");
	scanf("%s", &ans);
	char defo4[] = "ルイージ";
	strcat(log, defo4);
	if (checkanswer(ans, defo4, log) == 0)
		sum += 20;

	printf("問5:昨日の明日は?\n");
	scanf("%s", &ans);
	char defo5[] = "今日";
	strcat(log, defo5);
	if (checkanswer(ans, defo5, log) == 0)
		sum += 20;

	printf("あなたの得点:%d\n", sum);
	printf("あなたの回答:%s\n",log);
	return 0;
}

Re: 配列での文字列の扱いについて

Posted: 2022年12月06日(火) 18:10
by usao
配列 log の中身の初期状態が不定だからでは?

コード:

//例えばこんな感じに変えたら動作が変わりませんか?
char log[200] = { 0 };

Re: 配列での文字列の扱いについて

Posted: 2022年12月06日(火) 19:01
by みけCAT
エラーとは直接関係無さそうですが、2点気になるところがありました。
  • scanf() の書式 %s は char* 型のデータを要求するので、配列へのポインタ &ans (char(*)[100] 型) ではなく配列の戦闘要素へのポインタ ans (これは配列だが、sizeof などの例外を除いて式中では先頭要素へのポインタに変換される) を渡すべきである
  • log を「あなたの回答」というメッセージとともに出力しているが、log には入力されたデータではなくあらかじめ用意された正解のデータが格納されている
オフトピック
(あえて一般的でない正解にして意地悪をするなど) クイズの正解をどうするかは自由だと思うけど、
最近公開された映画は『すずめの戸締り』なんだよなあ…
映画『すずめの戸締まり』公式サイト

Re: 配列での文字列の扱いについて

Posted: 2022年12月06日(火) 20:03
by 幸尚
解決出来ているようですが配列などの変数を予め初期化する癖をつけておかないと思わぬバグで苦しむことになるのでお気をつけ下さい。