プロが教えるわが家の防犯対策術!

C言語で、Hit and Blow(3ケタの数字) を作りました。
数字以外が入力されたときにもう一度入力させるプログラムが分かりません。
例:ae42やrtg3などが入力された場合
どのように下のプログラムを改良すればよいか教えてください。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{
int num1, num2, num3;
int user, user1, user2, user3;
int hit, blow, count;


srand(time(0));
num1=rand()%10;
while (1) {
num2=rand()%10;
if (num2!=num1) {
break;
}
}
while (1) {
num3=rand()%10;
if (num3!=num1 && num3!=num2) {
break;
}
}
printf("%d%d%d\n",num3,num2,num1);


count=1;
printf("重複しない3つの数字:");
while(1) {
while (1) {
scanf("%d",&user);
user3=user/100;
user2=(user/10)%10;
user1=user%10;
if (user1!=user2 && user1!=user3 && user2!=user3) {
break;
}
printf("重複してます!重複しない3つの数字:");
}


if (user1==num1 && user2==num2 && user3==num3) {
break;
}


hit=0;
blow=0;
if (user1==num1) {
hit++;
}
if (user2==num2) {
hit++;
}
if (user3==num3) {
hit++;
}
if (user1==num2 || user1==num3) {
blow++;
}
if (user2==num1 || user2==num3) {
blow++;
}
if (user3==num1 || user3==num2) {
blow++;
}
printf("%dヒット%dブロー\n",hit,blow);
printf("次の数値:");
count++;
}
printf("%d回で当たりました!\n",count);
return 0;
}

質問者からの補足コメント

  • 032は、3ケタの数字に含み、16では再入力させるようにしたいです。

    No.1の回答に寄せられた補足コメントです。 補足日時:2016/05/24 18:54
  • 実際に動かしてみたのですが、プログラムが動きません。
    どのように改良したらよろしいのでしょうか?

    No.2の回答に寄せられた補足コメントです。 補足日時:2016/05/24 19:10
  • No.2を私の書いたプログラムのどこに入れればよいかがわかりません。
    色々と試したのですが、入力した数字やアルファベットにより、無限ループになります。

    No.3の回答に寄せられた補足コメントです。 補足日時:2016/05/25 00:29
  • ~~~~~
    scanf("%d",&user);
    if (user1!=user2 && user1!=user3 && user2!=user3) {
    break;
    }
    fgets(buf, BUF_SIZE + 1, stdin);
    if(!isdigit(buf[0])) continue;
    if(!isdigit(buf[1])) continue;
    if(!isdigit(buf[2])) continue;
    break;
    user = atoi(buf);
    printf("重複してます!重複しない3つの数字:");
    ~~~~~
    字数の関係ですべて打つことができなかったのですが、この箇所にNo.2を入れたのですが、
    アルファベットを加えると無限ループします。
    どこにNo.2を加えればよいのでしょうか。

    No.4の回答に寄せられた補足コメントです。 補足日時:2016/05/25 18:46

A 回答 (5件)

No.2です。



> どこにNo.2を加えればよいのでしょうか。

No.2のプログラムは、数字を入力して変数userに代入するものです。
ですから同じ動作をしている部分、すなわちscanf()と置き換えれば良いのです。



以下は、No.2のプログラムを修正して関数化したものです。

#include <ctype.h>と 関数input(){ }をmainの上に追加して、
scanf()を代入文に置き換えてみてください。

----------
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

// 関数
int input(void){
char buf[4];
int i;

while(1){
printf("重複しない3つの数字:");
// fflush(stdout);

for(i = 0; i < sizeof(buf); i++) buf[i] = 0;
fgets(buf, sizeof(buf), stdin);
if( buf[sizeof(buf)-2] != '\n' && buf[sizeof(buf)-2] != 0)
while( getchar() != '\n') ; // 入力バッファクリア(この行、要セミコロン)

if( !isdigit(buf[0]) ) continue; // 1文字目が数字かチェック
if( !isdigit(buf[1]) ) continue; // 2文字目が数字かチェック
if( !isdigit(buf[2]) ) continue; // 3文字目が数字かチェック
break;
}
return atoi(buf);
}

// メイン
int main(void){
int user;

user = input(); // scanfの代わり
printf("number : %d", user);

return 0;
}
----------
    • good
    • 1
この回答へのお礼

参考にしてプログラムを作っています。

お礼日時:2016/05/31 17:13

その「いろいろと試した」の具体例を書いてもらえませんか?



まあ, 最悪 getchar を使えばなんとでもなるんだけど.

なお fflush(stdin); は
https://oshiete.goo.ne.jp/qa/9287686.html
の回答では「実装依存」となっていますが, 正しくは「未定義動作」です. 規格に明確に「未定義」と書いてあるので「実装依存」と解釈してはならず (実装に依存するなら「処理系定義」とするのがふつう), 純粋に「未定義」であると解釈しなければなりません. 資料によってはこれで「入力バッファがフラッシュできる」となっていることもありますが, それは古代の資料としてみるべきです. もちろん規格上未定義動作である以上, 処理系が動作を定義することはまったく問題ありませんが, この質問では処理系が明記されていない以上未定義動作であるようなものを「回答」に加えるべきではないでしょう (「環境によっては」と書いてあるのでまだ良心的ではあるといえますが).
この回答への補足あり
    • good
    • 1

「実際に動かしてみたのですが、プログラムが動きません。

」ではなく, 具体的に「どう」動かないのかを書くべきだねぇ. あと, 細かいんだけど
016hogehoge
は OK? NG? 数字の前に空白はあっていいのかな?

ちなみに fflush(stdin); は一般にはやっていけない操作なので要注意.
この回答への補足あり
    • good
    • 0

こんな感じでどうですか?



一度配列に3文字を読み込み、それが全て数字だったら数値化する。
数字でなかったら、再度入力を促す。

※2か所のfflush()は環境によって、必要かもしれません。
--------
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define BUF_SIZE 3 // 3文字

int main(void){
char buf[BUF_SIZE + 1];
int user;

while(1){
// fflush(stdin);
printf("重複しない3つの数字:");
// fflush(stdout);

fgets(buf, BUF_SIZE + 1, stdin); // 配列bufに読み込む
if(!isdigit(buf[0])) continue; // 1文字目が数字かチェック
if(!isdigit(buf[1])) continue; // 2文字目が数字かチェック
if(!isdigit(buf[2])) continue; // 3文字目が数字かチェック
break;
}
user = atoi(buf); // 数値化する
printf("number : %d", user);

return 0;
}
この回答への補足あり
    • good
    • 0

本題とは関係ないような気もするんだけど, 例えば


032
は「3ケタの数字」と言っていいのかな? 同じように, 「重複しない3つの数字」と言っているときに
16
と入力するのは OK なのかな?
この回答への補足あり
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています