2011-12-17 27 views
0

私はC++を学んでいます。C++無限ループ

navは整数です。

無効な値を入力すると、有効な値を入力するようユーザーに求めています。

void main() 
{ 
    printf("Type an integer : "); 
    if(!scanf("%d", &nav)) 
    { 
     system("cls"); 
     printf("Invalid ! \n"); 
     main(); 
    } 
} 

最初の値を入力すると点滅します。それは画面を再読み込みするように点滅しています。私はそれが無限ループだと思う。

私は正しい方法でそれを行うことができますか?私は実際の番号を入力するまで、ユーザーからの番号を尋ねたい。

+0

は再帰的(メインの呼び出しは)少し奇妙です。 – JustJeff

+7

1) 'void main()'はC++では不正です。 2) 'main()'の呼び出しはC++では不正です。 –

答えて

3

ユーザが無効な入力を入力した場合、scanf()はそれを消費せず、同じ違反入力文字を永​​遠に覗いてしまいます。最初にユーザーが入力したものを読む必要があります。std::getline()を使用することをお勧めします。strtol()sscanf()、またはstd::istringstreamで解析してみてください。 atoi()は失敗を報告しないため、使用しないでください。

int nav; 
{ 
    string line; 
    while (getline(cin, line)) 
     if (istringstream(line) >> nav) 
      break; 
} 

EDIT:上記のロジックのではなく、美しい演出のためのコメントを参照してください。私は答えから外しました。なぜなら、a)私は他の人のアイデアを盗みたくはありませんし、b)私はC++に新しい人をその定式で提示するかどうか分からないのです。少なくとも。

P.S .: main()をC++で呼び出すことはできません。

+0

メインにはメインがあります:) – fazo

+0

@Marcelo Cantos、ありがとうございます。私のソースコードの使用例を教えていただけますか?私は新しいことを学んでいるC + +と私は自分のコードにこれを適応させることができませんでした。 – Eray

+1

これを 'for std :: string line; std :: getline(std :: cin、line)&&!(std :: istringstream(line)>> nav);){}'に圧縮することができます。 –

1

2つのもの。

Scanfは入力を処理する前に 'Enter'キーを押す必要があるため、点滅は次のキーを待っているカーソルに過ぎません。

また、mainからmainを呼び出すことはかなり非標準的です。あなたは 'while'ループを調べるべきです。

+0

"点滅はちょうど次のキーを待っているカーソルかもしれません。"いいえ、全画面が点滅し、画面を再読み込みしています。 – Eray

+0

他の2つの答えが正しいと思います。 。入力バッファーで待機している文字が一致しない場合、それは取り除かれず、次のscanfを実行すると再び取得され、画面が再びクリアされます。 – AShelly

0

あなたのプログラムは良いものではありませんが、何が起こっているか教えてくれます。

C/C++では、scanfが入力から整数(%d)を読み取れない場合は、何も読み取られません。つまり、scanfがintを読み取ることを妨げていたとしても、そこに残ります。次のscanfでは、同じ文字がエラーの原因になります。

例で説明します。あなたはこの入力から多くの整数を読んでいると想像:あなたは%dscanfを呼び出す場合

12 13 Shahbaz 15 

さて、あなたは12を読み取り、入力は次のようになります。

13 Shahbaz 15 

次は、%dscanfを呼び出し、 13と表示されます。今入力は次のようになります。

Shahbaz 15 

ここでも、あなたは%dscanfを呼び出します。ここで、入力はS(空白の後)で始まり、scanfは整数を読み取れなかったので失敗して戻ります。入力はそのままです(おそらく空白のために保存されます)。つまり、入力は次のようになります。

Shahbaz 15 

あなたが見ることができるように、%dで入力の読み取りがあなたに正確に同じエラーを与えるだろうし、あなたが無限ループで立ち往生しています。

は、この問題を解決するには、あなたは多くの選択肢を持っています。これは非常にあなたが状況を処理する方法に依存しますが、二つの方法が右printf("Invalid\n")を印刷した後(%c付き)文字または(%sとの)文字列を読んでどちらかになります。

第一の方法は次のように入力を処理するための良いです:

q
12 13 q14 15 

は無視する必要が間違いです。無効なデータが意味のある言葉ですが、あなたはちょうどそれらを無視したい

12 13 Shahbaz 15 

:第二の方法は次のように入力を処理するために良いです。

そして、私はscanfを使用したい場合の方法は、はそれを書くと、次のようになります。

int main() // always write int main 
{ 
    int nav; 
    printf("Type an integer: "); 
    while (scanf("%d", &nav) != 1) // scanf returns number of successful %'s read 
    { 
     printf("Invalid number. Try again: "); 
     scanf("%*s");    // read a %s but ignore it 
    } 
    // The rest of the program, using nav 
    return 0; 
} 
+0

なぜダウン投票?! – Shahbaz