<< bit で足し算 memo | main | #SW2 言語の習得 >>
Twitter


スポンサーサイト

一定期間更新がないため広告を表示しています

posted by: スポンサードリンク | - | | - | - | - | - |

不正な入力への対応

授業にて。次のような問題が出た。 じゃんけんを行うプログラムを作れ。ユーザには scanf で手を入力させる。次のような形式である。
scanf("%d %d", &moveA, &moveB);
手はグーを 1、チョキを 2、パーを 3とする。それ以外の入力が与えられた場合はやり直させる
こまったことに、それ以外の入力が与えられた場合はやり直させるというのが難しかったらしい。これの方法を考えてみる。

まず、まっさきに思いついたのが次の記述方法である。以下では問題を簡略化するために "1+4 の答えを入力させる問題" とする。

printf("Q. 1 + 4 = ");
scanf("%d", &answer);
while(answer != 5){ // もしも答えが違うなら
     printf("No, try again!¥n 1 + 4 =");
     scanf("%d", &answer);
}

だが、教授は「scanf が二回あるのは美しくない」と指摘。そこで以下の物を提案してみる。


printf("4 + 1 = "); // 前説

while((scanf("%d", &a)!=1) || (a != 5)){
// もしも scanf で得られた数字が 1 こではない
//          or
// もしも a が 5 ではないなら
    getchar(); // 最後の改行を破棄。今回のポイント
    printf("No, Try Again!¥n4 + 1 = "); // 次の入力を促す前説
}

printf("OK¥n");

while の条件文内に scanf を記述。scanf は読み込めたデータの数を返り値として返すので、 != 1 で一個以外の値を読み込んだならば、と条件式を書くことができる。

条件文は && で「双方が成立した場合は」、 || で「片方でも成立した場合は」という意味になる。今回の場合値を読み込めなかったケースと答えが間違っていたケースの双方を不正な入力として再入力を要求するためにループを回したいため、上記のように記述した。

最初の scanf で値をうまく読めなかったケースについて答えの数字の代わりに文字を打ち込んですぐにエンターを押してしまったケースを考えた。もしも、上記の getchar を外すと文字が入った場合において無限ループしてしまう。なぜだろう。 scanf で読み込んたあとの残りはバッファに残ってしまうそうだ (参考:inquisitor 数値をscanf()で読んだあと、文字列をfgets()で読む)。しかし、文字を入れてしまった場合、実際には何も読み込めてない。つまり、全て残ってしまう。これで残った文字を破棄。ちなみに、 scanf("%s"); とかだと数値を入れた際 (= scanf は上手く行ったけど間違った答えを入力した場合) にまた入力を求めてきたのでにょーん。

posted by: しゅんしゅん | 学び | 23:59 | comments(0) | trackbacks(0) | - | - |

スポンサーサイト

posted by: スポンサードリンク | - | 23:59 | - | - | - | - |
コメント
 









トラックバック
 
http://syun2ej.jugem.jp/trackback/3337