重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【6/2終了】教えて!goo新規会員登録

do whileの文で
do{…
}while(c!=1 && c!=2 && c!=3);
つまり1,2,3以外の数字を入力した場合はループするようにしました。…は無限ループしないようにしています。実際1,2,3以外の数字を入力しても無限ループしません。しかし、数字以外の文字を入れてしまうと、無限ループします。%dがいけないのでしょうか?初心者ですので分かりやすくよろしくお願いします。多分これだけじゃ情報不足だと思うので、足りない情報があれば言ってください。すぐに書き込みます。

A 回答 (12件中1~10件)

#10です。



ようやく意味が分かったような気がします。
たぶん、do while内に元々あったscanf("%d" ,&c);が残ってませんか?
もしそうであればscanf("%d" ,&c);は削除してください。

#10の対策は、元々あったscanf()をif文に含めるイメージでしたが、伝わりにくかったようですね。

scanf("%d" ,&c);     この一行を 
  ↓ ↓ ↓  
if(scanf("%d",&c)==0)   このように
{               変える
scanf("%*s");       イメージ
c=0;             でした。
}
    • good
    • 0
この回答へのお礼

ご回答ありがとうございました。丁寧に教えていただきありがとうございます。本当に助かりました。
あと少し問題が残っていますが、何とか自分でやってみます。できなかった時はまた質問します。本当にありがとうございました。

お礼日時:2005/06/03 22:10

#10です。



その部分の入力処理を繰り返すということは、cに1~3以外が入っているときになります。
1を入力して結果が出るなら、九九を表示するまではc=1のはずです。
しかし、再度入力待ちになるということは、この間でcの値が変わってしまったということになります。でも、ソースを見る限りそのような悪さをしている部分が見つかりません。
それにc=1ならif(c==1)break;でループを抜けていくはずなのに、do whileの条件で繰り返すというのも変ですね。
考えられるとしたら、修正ミスや括弧の対応がおかしくなったとかでしょうか。
a,b,cにどのような値を入力したときでしょうか?また、再現性はありますか?
現状のdo while間のソースを見てみたいです。


ついでなので
do whileの部分とは関係ないですが、他の環境でwhile(1)がループしないということが考えられます。
次のif文でb<=20となってますが、自動変数bは初期化されてないので偶然20以下の値が入ることがあります。
その場合、すぐに終わってしまいますね。
今は値の大きなゴミが入っているので問題が露見せず、動作しているようです。
その下でbを入力させているので、初期値に21でも入れておけば誤動作は少なくなるでしょう。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
実はcの値が変わったわけじゃなく

 そのまま表示する場合は1、入力し直す場合は2、 終了する場合は3を押してください。
 数値入力:1
 5

と入力した場合2回目に入力した5は無視され、1の実行結果になります。ようするに、上記の場合は、1を入力した後にそのまま、プログラムを作動させたいのです。a,bでも同様のことが起きます。
pareoparaさんい教えていただいき入力し直したプログラムを張りたいのですが、文字数オーバーのようです。
pareoparaさんに教えていただいたプログラムを入力してない時は、文字キーを入力すると無限ループになるのはcだけなのでa,bには適応させてません。もし問題が解決したら適応させようと思います。
2回目の入力を求められなければ完璧です。(実はもうひとつ意味が分からない事が起きているのですが、それはまた今度にします。)どうか本当によろしくお願いします。

お礼日時:2005/06/03 01:24

> 主旨以外のプログラムのダメだしはご遠慮ください


とのことですので、無限ループに陥った原因と対策だけ書きます。

原因:
scanf()の%dは数字以外の文字は取り出しません。
取り出さない文字列はずっと入力バッファに残ったままです。
そのため、一度数字以外が入力されるとa,b,cのscanf()は残っている入力バッファから値を取り出そうとします。
しかし、数字ではないので取り出さないで終わるという動きをするため、無限ループになります。


対策:
各scanf()を以下のようにエラーチェックするようにして、バッファの文字列を捨てる処理を入れてみてください。
あと、自動変数a,b,cは初期値が設定されていないので、初回のscanf()に失敗した場合、値が不定(ゴミが入っている)です。
そのため、次のif文が成立しない可能性があります。
scanf()が失敗したとき、それぞれの変数に初期値(例えば0)を入れてあげれば良いと思います。

if (scanf("%d", &a) == 0) /* 入力バッファから取り出し失敗 */
{
scanf("%*s"); /* 文字列を入力バッファから破棄 */
a= 0; /* 初期値設定 */
}

こんな感じでb,cについても直します。
実はこれだけではまだ不十分ですが、まずはこの形で完成を目指してください。
    • good
    • 0
この回答へのお礼

丁寧なご回答本当にありがとうございました。数字以外のキーを入力した場合は確かに僕が望んでいるとおりの結果になりました。しかしまた問題が・・・。今度は数字(1,2,3、に限らず全部の数字)を入力した場合、その後、もう一度scanfが作動してしまったようで、また入力を求められます。
・正常な場合

 そのまま表示する場合は1、入力し直す場合は2、終了 する場合は3を押してください。
 数値入力:1

この場合1を入力したとして、ENTERを押したら1の結果になります。しかし
・新たな問題

 そのまま表示する場合は1、入力し直す場合は2、終了 する場合は3を押してください。
 数値入力:1
 1

となり、もう一度数字を入力しなければなりません。
数字以外のキーを押したときは、正常に作動します。
なんとかなりませんでしょうか?
しつこいようですがよろしくお願いします。

お礼日時:2005/06/02 15:32

こんばんは。

yasuyuki007です。
要約すると、「1,2,3以外の数字(文字も含む)入力でループして、1,2,3の数字入力でループから脱出する」ということでよろしいでしょうか?
    • good
    • 0
この回答へのお礼

はい。要するに1,2,3以外を打ち込めば、また打ち直させる感じです。よろしくお願いします。

お礼日時:2005/06/02 01:11

こんばんは。

yasuyuki007と申します。
私の環境(Borland C++ 5.5.1)でNo.6のお礼の所に記載されていたプログラムをコンパイル&実行してみました。結果は、
1,2,3以外の数字入力で、無限ループします。
数字以外の文字入力で、無限ループしません。

ですから、プログラムそのものは正しいと思いますけど、いかがでしょうか?
もし、数字以外の文字入力で無限ループするようにしたいと思われるのでしたら、その旨を書き込んで下さい。よろしくお願いします。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
>1,2,3以外の数字入力で、無限ループします。
 数字以外の文字入力で、無限ループしません。
1,2,3以外の数字入力で、無限ループしないで、数字以外の文字入力で、無限ループするのですが・・。
僕がしたいのは、
"bが20を越えています。正常に表が表示されません。
そのまま表示する場合は1、入力し直す場合は2、やめる場合は3を押してください。"
が表示された時、1,2,3以外、もしくは文字(数字以外のキー)を入力した場合
"1、2、3のどれかを入力してください。"と表示させまた、
"bが20を越えています。正常に表が表示されません。
そのまま表示する場合は1、入力し直す場合は2、やめる場合は3を押してください。"
っていうのまでループさせたいのです。今のところ1,2,3以外の数字では出来るのですが、数字以外のキーを入力してしまうと無限ループしてしまうのです。指定のところまでにループさせて、条件がそろえばループを脱したいのです。決して無限ループさせたいわけではありません。なんとかできないでしょうか?説明が下手で誠に申し訳ありません。どうかよろしくお願いします。

お礼日時:2005/06/01 23:20

最初から「多分これだけでは情報不足だと思うので~」と書くこと自体が問題のような気はします (少なくとも自分では「十分である」と思うだけの情報をだすべき) が, それはそれとして scanf で読み込めたかどうかは返り値でわかりますね, 一応.


「fgets を使う」のが正論ではありますが, わりきった上で scanf を使うのもありだと思う.
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
>最初から「多分これだけでは情報不足だと思うので~」と書くこと自体が問題のような気はします。
下記にプログラムを表示しましたが、初心者なのでどこまでの情報が問題解決に必要なのか全然わかりません。できればプログラムを表示せずに回答が欲しかったです。しかしsunasearchさんが言われるようにループ内を表示したほうがよいとなると全部表示しないと意味わからないなと思い表示しました。
もしよろしければ下記のプログラムを見て、問題の解決法が見つかれば教えてください。よろしくお願いします。

お礼日時:2005/06/01 09:41

#1です。



>実際1,2,3以外の数字を入力しても無限ループしません。

ということですので、文字が入力うんぬん以外のバグがあると思うので、そちらを先に対処された方が良いと思いますよ。

変数cの宣言と、ループにはいる時の初期値。
ループ内でcを使った演算を示してもらえると、回答が付くかと思います。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
プログラムを下記に書きます。
ループ内だけを表示しても多分意味分かんないと思うので。プログラムは自分で縦、横の範囲を決めて掛け算の表を作るプログラムです。

/*掛け算の表*/
#include <stdio.h>
int main(void)
{

int a,b,c,x,y;
printf("掛け算の表です。自分で縦と横の範囲を指定できます。\n");
/*while文は最後まで*/
while(1){
if(b<=20)break;
printf("aとbに整数を入力してください(a:縦 b:横)。\n");
printf("ただしbに代入する数字は20までとします。\n");
printf("a=");
scanf("%d" ,&a);
printf("b=");
scanf("%d" ,&b);
printf("\n");
if(b<=20){
/*九九プログラム*/
printf("a:縦 b:横\n");
printf("\n");
for(x=1; x<=a; x++){
for(y=1; y<=b; y++){
printf("%4d" ,x*y);
if(y==b)
printf("\n");
}
}
/*ここまで*/
}
else if(b>=21){
printf("bが20を越えています。正常に表が表示されません。\n");
do{
printf("そのまま表示する場合は1、入力し直す場合は2、終了する場合は3を押してください。");
printf("数値入力:");
scanf("%d" ,&c);
printf("\n");
if(c==2){
printf("");
}
/*if*/
else if(c==1){
/*九九プログラム*/
printf("a:縦 b:横\n");
printf("\n");
for(x=1; x<=a; x++){
for(y=1; y<=b; y++){
printf("%4d" ,x*y);
if(y==b)
printf("\n");
}
}
/*ここまで*/
if(c==1)break;
}
/*if終了*/
else if(c==3)
printf("終了します。\n");
if(c==3)break;
else if(c!=1 && c!=2 && c!=3)
printf("1、2、3のどれかを入力してください。\n");
}while(c!=1 && c!=2 && c!=3);
}
if(c==1)break;
if(c==3)break;
}
/*while終了*/
return 0;
}

/* */は自分が分かるようなメモみたいな感じなので気にしないでください。
なお、初心者なりに一生懸命作った文なので質問の主旨以外のプログラムのダメだしはご遠慮ください(勝手言ってすみません)。よろしくお願いします。

お礼日時:2005/06/01 09:35

> cの範囲を指定してもまた無視されませんか?


> 何度も質問してすみませんが、よろしくお願いします。

いちいち訊かんとやってみたらええやないの。

c = 0;
scanf("%d",&c);
if ( ヤバい入力 ) break;
    • good
    • 0
この回答へのお礼

何度もご回答本当にありがとうございます。返事が遅くなりすいません。がんばって試してみます。

お礼日時:2005/06/01 09:26

> scanf("%d",&c) があります。

どうやれば阻止できますか?

scanfなんか使わないのが一番。

gets/fgetsで文字列として取り込み、文字列→数値変換を行います。変換に失敗したらbreak。
    • good
    • 0

> scanf("%d",&c) があります。

どうやれば阻止できますか?

scanfの直後、ヤバい入力だったら break すればいい。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。breakとはif(条件)break;のことですよね?条件はどうしたらよいのですか?cの範囲を指定してもまた無視されませんか?何度も質問してすみませんが、よろしくお願いします。

お礼日時:2005/05/31 11:26

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