下記のプログラムですがまずc言語でlevel個の文字列を記憶させます。その後その文字列を0.5秒ほど表示して消し、コンピュータによって指示された番号の文字を当てることを複数回繰り返すプログラムです。
たとえば問題としてABCDEFがでて、その後3が指定されるとCと答えるようにしたいのです。
しかしループの奇数回目の時にscanfが認識がされていない(?)ようで答えを打ち込むことができず勝手に不正解になってしまい自分でプログラムを見直しても間違っている場所が分かりませんでした。
回答よろしくお願いします。
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#define MAX_STAGE 10
#define MAX_LEVEL 10
#define MIN_LEVEL 3
int sleep(unsigned long x){ /*時間をxミリ秒潰す*/
clock_t c1 = clock(),c2;
do{
if((c2=clock()) == (clock_t)-1)
return(0);
}while(1000.0 * (c2 -c1) / CLOCKS_PER_SEC < x);
return(1);
}
int main(void){
int stage;
int success = 0;
int level;
clock_t start,end;
srand(time(NULL));
printf("いくつかの文字を記憶しましょう\n");/*レベルの設定*/
do{
printf("レベルを%d以上%d以下で入力してください\nLEVEL:",MIN_LEVEL,MAX_LEVEL);
scanf("%d",&level);
}while(level >MAX_LEVEL || level<MIN_LEVEL);
start = clock();/*本体スタート*/
for(stage = 0;stage < MAX_STAGE;stage++){
char *no;
int i,j,k;
char alpha[] = "abcdef";
int ans;
char kotae;
no = calloc(level+1,sizeof(char)); /*答えが含まれる文字列の領域を確保*/
for(i=0;i<level;i++)/*記憶する文字列の作成*/
no[i] = alpha[rand() % 6];
no[i] = '\0';
printf("%s",no); /*答えが含まれる文字列を表示*/
fflush(stdout);
sleep(500);
ans = rand() % level; /*答える文字を決定*/
printf("\r%d番目の文字を答えよ:",ans + 1);
scanf("%c",&kotae);
if(no[ans] != kotae)
printf("不正解です\n");
else{
printf("正解です\n");
success++;
}
}
end = clock();
printf("%d回中%d回成功しました。\n",MAX_STAGE,success);
printf("%.1f秒でした。\n",(double)(end - start) / CLOCKS_PER_SEC);
return(0);
}
No.4ベストアンサー
- 回答日時:
scanfにて%cを指定したとき、この現象は発生します。
最初のscanf("%c",&xx)で何か値を入力した後エンターキーを押しますよね。そのエンターキーの情報が入力バッファに残っているため、次のscanfにて、エンターキーの文字コードを読んでしまうのです。
対策としては、scanf の前に fflash(stdin) を入れるのが確実です。
また、scanf(" %c",&xx) というように%cの前にスペースを入れることでも解決できますが、あまりお勧めはしません。
「scanf」「バッファ」でぐぐれば、この件に対するサイトを見つけることができます。
scanf関数は非常に便利に見えて、色々使いにくいところがあります。
ある程度慣れてきたら、一行(あるいは1文字)ずつ読み込んで、自分のプログラム内で解析する方法も勉強したほうが良いと思います。
No.5
- 回答日時:
先ほどfflash(stdin)とすれば確実と言いましたが、fflashはにstdinを指定した場合の処理は処理系に依存します。
すみませんでした。そこで、getchar() を使うのはいかがでしょうか?
cyacya2000さんが仰っているscanfによってバッファに\nが残る ということは初めて知ったことでした。
早速教えていただいた方法でプログラムしてみます。
検索するキーワードも教えていただいたので後ほどぐぐって調べさせてもらおうと思います。
回答ありがとうございました。
No.3
- 回答日時:
>fflush(stdin); が正しいのではないでしょうか?
正しくありません。
標準入力に対するfflushは未定義の動作です。
なお、これは、質問者さんのプログラムで
fflush(stdout);
が必要かどうか、という話とは別です。
No.2
- 回答日時:
fflush(stdout); は出力(print)のバッファだと思います。
この場合は入力(scanf)のバッファを消したいので、
fflush(stdin); が正しいのではないでしょうか?
もしくは scanf("%c",&kotae); 部分に scanf("%c%c",&kotae,&dummy); のような改行文字用のダミーを追加するのが有効だと思います。
参考URL:http://www9.plala.or.jp/sgwr-t/lib/fflush.html
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語 3 2022/10/04 15:07
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
数字以外が入力されたらエラー...
-
正負を反転させて出力するプロ...
-
プログラミング初心者です。 Py...
-
java初心者です。入力されたの...
-
プログラミングの問題です 「金...
-
入力値が1以下、かつ数字以外の...
-
C言語でつるかめ算をするにはど...
-
scanfが2回使えない・・・?;
-
scanf が無視されます
-
小数か整数かを判定する方法
-
enterでループ終了
-
Eclipseコンソール表示を、リセ...
-
scanf関数 バッファに残ったエ...
-
getchar()について 教えてくだ...
-
Excel VBAで、Application.Inpu...
-
C言語初心者です。ファイルの読...
-
VisualStudio2019のコードアナ...
-
あるキーを押したら強制終了さ...
-
gets_sがうまく動かない
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
*をユーザーが入力した数字の数...
-
正負を反転させて出力するプロ...
-
数字以外が入力されたらエラー...
-
プログラミング初心者です。 Py...
-
double型が正常に認識されてい...
-
java初心者です。入力されたの...
-
Eclipseコンソール表示を、リセ...
-
scanfが2回使えない・・・?;
-
C言語scanf_sで何故か2回入力に...
-
if文の条件にscanf関数を使うと…?
-
Linuxで入力待ちなしkeyread関...
-
プログラミングの問題です 「金...
-
ワードで文字を入力する時の変...
-
cout関数を使っているのですが...
-
batプログラム上で文字列を入力...
-
Userformの入力順序をタブオー...
-
scanf が無視されます
-
C言語 逆ピラミッドの作り方
-
gets_sがうまく動かない
-
Excel VBAで、Application.Inpu...
おすすめ情報