タイピングゲームを作成しています。

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

タイピングゲームを作成しています。

#1

投稿記事 by masuter » 6年前

タイピングゲームをつくってこいという課題がでています。
なんとなくはできたのですが、以下のエラーを解決できません。

1>課題4.c(56): warning C4047: '関数': 間接参照のレベルが 'const char *' と 'int' で異なっています。
1>課題4.c(56): warning C4024: 'puts': の型が 1 の仮引数および実引数と異なります。
1>課題4.c(54): warning C4473: 'scanf_s': 書式文字列として渡された引数が不足しています
1> 課題4.c(54): note: プレースホルダーとそのパラメーターには 2 の可変個引数が必要ですが、1 が指定されています。
1> 課題4.c(54): note: 不足している可変個引数 2 が書式文字列 '%s' に必要です
1> 課題4.c(54): note: この引数はバッファー サイズとして使用されま

コード:

//////////////////////////////////////////////////////////////////////
//
// タイピングのプログラム typing.c
//
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h> // system()
#include <string.h> // memset()

#define STRN 50
#define WORD 20
int main()
{

	char state[WORD][STRN] = { "matsue","college","of","technology" };	//state1~state3を初期化(問題文(STRN-1文字以内)を各自決める)
	//半角文字とする


	//できる人はstate1~state3を文字列の配列state[3][STRN]として改良してみてください)


	char userstr[STRN];	//ユーザが入力した文字列を保存する配列

	int i;
	int j;
	int errcount;	//入力ミスの文字数をカウント
	int strcount;	//問題文の全文字数をカウント

	char key[STRN];		// 再チャレンジの有無を示す文字列を保存する変数

	do {
		//errcount, strcountを初期化
		errcount = 0;
		strcount = 0;

		memset(userstr, 0, sizeof(userstr));//配列userstrをすべて0で初期化(前回入力された文字列を0にリセットする)

											//案内文の表示
		printf("これから3つの文が表示されます。1文表示されたら正確に入力してください。\n\n");

		//画面消去
		system("cls");

		// 問題 [1]
		for (j = 0; j < WORD; j++) {
			for (i = 0; i < STRN; i++) {
				puts("i");
				scanf("%s", &userstr[i]);
				strcount++;
				if (puts(i) != userstr[i]) {
					errcount++;

				}
			}
		}

			//結果表示
			printf("入力ミス:%d文字(%d文字中) 正解率:%d[%%]\n\n",	//画面に半角の「%」を表示する場合は「%%」と記述
				errcount, strcount, (strcount - errcount) / strcount);	//正解率 = 問題文3つの全文字数に対し,正しく入力した文字数の割合[%]

												//繰り返し実行するかどうか
			printf("もう一度チャレンジしますか? [y/n]>");
			gets_s(key, 49);	//文字入力


		} while (key[0] == 'y' || key[0] == 'Y');//key[0]が'y'か'Y'だったら繰り返す
		printf("\n");
		return 0;
	}
どう修正すればいいですか?

アバター
purin52002
記事: 235
登録日時: 7年前
連絡を取る:

Re: タイピングゲームを作成しています。

#2

投稿記事 by purin52002 » 6年前

提示しているコードは正しいですか?

コードのコメントにはtyping.cと書いてありますが、エラーログには課題4.cと書いてあります。
あとscanf_s関数も見当たりません。

もしかして違うファイルをコンパイルしようとしてたりして、、、?
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

masuter

Re: タイピングゲームを作成しています。

#3

投稿記事 by masuter » 6年前

purin52002 さんが書きました:提示しているコードは正しいですか?

コードのコメントにはtyping.cと書いてありますが、エラーログには課題4.cと書いてあります。
あとscanf_s関数も見当たりません。

もしかして違うファイルをコンパイルしようとしてたりして、、、?
typing.cというひな形ファイルを元に、課題4.cを作成しております。

アバター
purin52002
記事: 235
登録日時: 7年前
連絡を取る:

Re: タイピングゲームを作成しています。

#4

投稿記事 by purin52002 » 6年前

うーん、、、わからない^^;

とりあえず気になったところだけあげて行きます。

48行目
もしもvisualstudioで書いているなら、scanfを使うとscanf_sを使えと怒られてしまうので置き換えたほうがいいかも

50行目
putsにint型のiを渡していますが、putsには文字列を渡す必要があるのでitoa関数などで文字列型にしたほうがいい気がする。

50行目
putsとuserstrを比較しているが、putsの返り値は正の値かEOFなので期待している動作にはならなさそう。

warningの原因になりそうなのはこれぐらいしか見つけられませんでした^^;
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

かずま

Re: タイピングゲームを作成しています。

#5

投稿記事 by かずま » 6年前

masuter さんが書きました:タイピングゲームをつくってこいという課題がでています。
なんとなくはできたのですが、以下のエラーを解決できません。
warning(警告)や note(注意) は error(エラー) ではありません。
だから、実行できます。そこでエラーになるでしょう。
期待する実行例を想定して書いてもらえませんか?

「printf("これから3つの文が表示されます。」の直後に
system("cls"); を実行したら、printf の意味がないと思いませんか?
3つの文の表示はどこにあるんですか?
4つの単語ではないのですか?
パーセントを表示したいのなら 100倍してから割り算しないといけないのでは?
int puts(const char *) の使い方をご存知ですか?
masuter さんが書きました:どう修正すればいいですか?
とりあえず、次のように修正すると動きませんか?

コード:

    char state[WORD][STRN] = {
        "matsue","college","of","technology", ""
    };

コード:

        for (j = 0; state[j][0] != '\0'; j++) {
            printf("%2d: %s\n    ", j+1, state[j]);
            scanf_s("%s", userstr, STRN);
            for (i = 0; state[j][i] != '\0'; i++) {
                strcount++;
                if (userstr[i] == '\0' || state[j][i] != userstr[i]) {
                    errcount++;
                }
            }
        }

?で終わっている質問にはすべて答えてください。

かずま

Re: タイピングゲームを作成しています。

#6

投稿記事 by かずま » 6年前

gets_s(key, 49); を
scanf_s("%s", key, STRN); に修正してください。

エラーメッセージの出たソースプログラムを貼ってください。

masuter

Re: タイピングゲームを作成しています。

#7

投稿記事 by masuter » 6年前

期待する実行例を想定して書いてもらえませんか?
/////////////////////////////////////////////////////////////////
これから3つの文が表示されます。1文表示されたら正確に入力してください。
1:matsue
>>
2:college
>>
3:of
>>
4:technology
>>

入力ミス: 〇文字(〇文字中) 正解率: 〇%

もう一度チャレンジしますか? [y/n]>
///////////////////////////////////////////////////////////////////
「printf("これから3つの文が表示されます。」の直後に
system("cls"); を実行したら、printf の意味がないと思いませんか?

コード:

printf("これから3つの文が表示されます。1文表示されたら正確に入力してください。\n\n");

		//画面消去
		Sleep(3000);
		system("cls");
と修正しました。

とりあえず、次のように修正すると動きませんか
現在、修正したコードです。

コード:

#include <stdio.h>
#include <stdlib.h> // system()
#include <string.h> // memset()
#include <Windows.h>

#define STRN 50
#define WORD 20
int main()
{

	char state[WORD][STRN] = { "matsue","college","of","technology",""};//state1~state3を初期化(問題文(STRN-1文字以内)を各自決める)
																		//半角文字とする


																		//できる人はstate1~state3を文字列の配列state[3][STRN]として改良してみてください)


	char userstr[STRN]; //ユーザが入力した文字列を保存する配列

	int i;
	int j;
	int errcount;//入力ミスの文字数をカウント
	int strcount;//問題文の全文字数をカウント

	char key[STRN];// 再チャレンジの有無を示す文字列を保存する変数

	do {
		//errcount, strcountを初期化
		errcount = 0;
		strcount = 0;

		memset(userstr, 0, sizeof(userstr));//配列userstrをすべて0で初期化(前回入力された文字列を0にリセットする)

											//案内文の表示
		printf("これから3つの文が表示されます。1文表示されたら正確に入力してください。\n\n");

		//画面消去
		Sleep(3000);
		system("cls");

		// 問題 [1]
		for (j = 0; state[j][0] != '\0'; j++) {
			printf("%2d: %s\n    ", j + 1, state[j]);
			scanf_s("%s", userstr, STRN);
			for (i = 0; state[j][i] != '\0'; i++) {
				strcount++;
				if (userstr[i] == '\0' || state[j][i] != userstr[i]) {
					errcount++;
				}
			}
		}

		//結果表示
		printf("入力ミス:%d文字(%d文字中) 正解率:%d[%%]\n\n", //画面に半角の「%」を表示する場合は「%%」と記述
			errcount, strcount, (strcount - errcount)*100 / strcount);//正解率 = 問題文3つの全文字数に対し,正しく入力した文字数の割合[%]

																	//繰り返し実行するかどうか
		printf("もう一度チャレンジしますか? [y/n]>");
		scanf_s("%s",key, STRN);//文字入力


	} while (key[0] == 'y' || key[0] == 'Y');//key[0]が'y'か'Y'だったら繰り返す
	printf("\n");
	return 0;
}
ビルドすると、

コード:

1>------ すべてのリビルド開始: プロジェクト:課題4.c, 構成:Debug Win32 ------
1>  課題4.c
1>c:\users\keisuke\documents\visual studio 2015\projects\課題4.c\課題4.c(48): warning C4566: ユニバーサル文字名 '\u00A0' によって表示されている文字は、現在のコード ページ (932) で表示できません
1>  課題4.c.vcxproj -> C:\Users\Keisuke\documents\visual studio 2015\Projects\課題4.c\Debug\課題4.c.exe
1>  課題4.c.vcxproj -> C:\Users\Keisuke\documents\visual studio 2015\Projects\課題4.c\Debug\課題4.c.pdb (Full PDB)
========== すべてリビルド: 1 正常終了、0 失敗、0 スキップ ==========
実行結果は、
/////////////////////////////////////////////////////////////////
これから3つの文が表示されます。1文表示されたら正確に入力してください。
1:matsue
??
2:college
??
3:of
??
4:technology
??

入力ミス: 〇文字(〇文字中) 正解率: 〇%

もう一度チャレンジしますか? [y/n]>
///////////////////////////////////////////////////////////////////
とちゃんと入力できて判定もきちんとできますが、'??'が気になります。

かずま

Re: タイピングゲームを作成しています。

#8

投稿記事 by かずま » 6年前

masuter さんが書きました: 実行結果は、
/////////////////////////////////////////////////////////////////
これから3つの文が表示されます。1文表示されたら正確に入力してください。
1:matsue
??
2:college
??
3:of
??
4:technology
??

入力ミス: 〇文字(〇文字中) 正解率: 〇%

もう一度チャレンジしますか? [y/n]>
///////////////////////////////////////////////////////////////////
とちゃんと入力できて判定もきちんとできますが、'??'が気になります。
1 の次が全角のセミコロンで、2 の次が半角のセミコロン。
「入力ミス: 〇文字(〇文字中) 正解率: 〇%」は伏字だらけ。
実行結果は実際のものではありませんね。

次のように本物を [ code=text] で貼り付けてください。

コード:

これから3つの文が表示されます。1文表示されたら正確に入力してください。

 1: matsue
    matue
 2: college
    college
 3: of
    off
 4: technology
    technology
入力ミス:3文字(25文字中) 正解率:88[%]

もう一度チャレンジしますか? [y/n]>n
matsue の s が抜けているのと、
of に余計な f が付いているのとで、
ミスは 2文字かと思いきや 3。

これは matsue の sue が一致しないから 3。
of は「正解の 2文字」と一致するから 0。

これでいいんでしょうか?

?? が出るのは、printf("%2d: %s\n ", j + 1, state[j]);
の 4つのスペースが、0x20 0xa0, 0x20, 0xa0 になっているからです。
0x20 は ASCII の SP。0xa0 は ISO 8859-1 の NBSP(no-breack space)。
これはどうやって入力したのですか?

一つ訂正。
errcount の判定に、「userstr == '\0' ||」は不要で、
「if (state[j] != userstr) {」で十分でした。

「3つの文が表示されます」で、4つの単語が出るのはいいんですか?
それと、元のプログラムでどうして puts を使ったのですか?

masuter

Re: タイピングゲームを作成しています。

#9

投稿記事 by masuter » 6年前

すみません、いろいろとご指摘ありがとうございます。
なんか言われたことをそおのままやってただけじゃ上達しないなと思ったので、自分で1から調べてつくりなおしました。
見ていただきたいです。

コード:

//////////////////////////////////////////////////////////////////////
//
// タイピングのプログラム 課題4.c
//						
//////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdlib.h> // system()
#include <string.h> // memset()
#include <Windows.h>//Sleep()
#include <time.h>//時間計測

#define STRN 25

int main()
{
	char state[][STRN] = { "matsue","college","of","technology" }; //単語設定

	int i; //ループ用変数
	clock_t start, end;//時間計測
	char userstr[STRN];	//ユーザが入力した文字列を保存する配列
	char key[STRN];//再チャレンジの有無を示す文字列を保存する変数

	do {

		memset(userstr, 0, sizeof(userstr));//配列userstrをすべて0で初期化(前回入力された文字列を0にリセットする)
		int errcount = 0;//入力ミスした単語数のカウント
		int strcount = 0;//問題数のカウント

		printf("これから単語が表示されます。表示されたら正確に入力してください。\n\n");
		Sleep(3000);//3s何もしない
		system("cls");//画面消去

		for (i = 0; state[i][0] != '\0'; i++) {//state[i]の文字列の終わりまで繰り返す。
			start = clock();//時間計測開始
			printf_s("%s\n>>", state[i]);//state[i]の単語表示
			strcount++;//問題数カウント
			gets_s(userstr, STRN - 1);//文字列取得
			if (strcmp(state[i], userstr) != 0) {//判定
				errcount++;//入力ミスカウント
			}
		}
		end = clock();//時間計測終了
		printf_s("\n\n");
		printf_s("%d問中%d門正解しました。\nタイム:%ds\n\n", strcount, strcount - errcount, end / CLOCKS_PER_SEC);//結果表示
		printf("もう一度チャレンジしますか? [y(yes)/n(no)]>>");//再チャレンジの有無
		gets_s(key, STRN - 1);//文字列取得
		printf_s("\n\n\n\n");
	} while (key[0] == 'y' || key[0] == 'Y');//key[0]が'y''Y'であれば繰り返す。
	return 0;
}

実行結果

コード:

これから単語が表示されます。表示されたら正確に入力してください。 

matsue
>>matsue
college
>>college
of
>>of
technology
>>technology
フフフフΓッD・#
>>a
蕷戉`"/。ッKK
>>a
!
>>a


7問中4門正解しました。
タイム:19s

もう一度チャレンジしますか? [y(yes)/n(no)]>>

このようにわけのわからない文字が、毎度'3回'ひょうじされておわります。
stateの[0]つまり文字列の一番最初の要素が'\0'ではない間繰り返す としたつもりですがなぜでしょうか。

かずま

Re: タイピングゲームを作成しています。

#10

投稿記事 by かずま » 6年前

masuter さんが書きました:このようにわけのわからない文字が、毎度'3回'ひょうじされておわります。
stateの[0]つまり文字列の一番最初の要素が'\0'ではない間繰り返す としたつもりですがなぜでしょうか。

"technology" のあとに ,"" がないからです。
clock() の使い方が間違っています。time(0) をおすすめします。

返信

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