2016-11-19 20 views
3

解決策についてはフォーラムを検索しましたが、私のコードが生成する出力についてはまだ混乱しています。c - whileループは不正入力後にscanfを無視し続けます

だから、プログラムはかなり簡単です。

ファイルの最後に達するまで、入力で2つの数字が得られます。
入力が悪い場合は、エラーをstdoutに出力し、次のペアに進む必要があります。
両方が素数の場合は、primeが出力されます。それ以外の場合は、GCDが印刷されます。

入力が悪い、つまりどちらか一方または両方の数字が実際に数字でない場合、プログラムはscanfをスキップし、stderrに印刷エラーを継続します。
デバッグ中に、次のすべての反復が完了すると、何も入力されなかったかのように0が返されます。scanf()
プログラムは常にstderrに出力するので、プロンプトは入力のために非アクティブです。

ndおよびnsdは、それぞれ最大の除数および最大公約数を返す関数です。

メインプログラムは以下の通りです:

#include <stdio.h> 
#include "nd.h" 
#include "nsd.h" 

int main() 
{ 
int a; 
int b; 
int inp_status = 0; 
while (1){ 
     inp_status=scanf(" %d %d", &a, &b); 
     if (inp_status == EOF){ 
      break; 
     } else if (inp_status < 2){ 
      fprintf(stderr, "Error: bad input\n"); 
     } else { 
      if (a == 1 || b == 1){ 
       printf("1\n"); 
      } else if (nd(a) == 1 && nd(b) == 1){ 
       printf("prime\n"); 
      } else { 
       printf("%d\n",nsd(a,b)); 
      } 
     } 
} 
fprintf(stderr, "DONE\n"); 
return 0; 
} 
+1

好奇心は、@Levは、なぜコードが代わりに ''のscanf() 'の'のfgets()を使用していませんか? – chux

+0

正直なところ、私は 'fgets()'を使った行処理はC言語では適切な文字列型を見ていないので、もっと難しいと考えました。また、入力ストリームをリンクしてリンクしたり、次の反復で再度そのストリームにアクセスすることはできません。 stderrはそれを引き起こしますか? –

+2

入力に '' A''と入力されている場合、 'scanf'はそれを過ぎようとしているままになります。 @chuxは言うように、 'fgets'を使い、' sscanf'をその文字列に適用します。失敗した場合は、文字列全体をダンプして別の文字列を取得することができます。それで、あなたは次のコメントでその恐ろしい回避策を避けます。 –

答えて

0

私は一緒に、戻り値を検証するための簡単なプログラムを置く: INP INP

#include <stdio.h> 

int main() 
{ 
    int a; 
    int b; 
    int inp_status = 0; 

    inp_status = scanf(" %d %d", &a, &b); 
    printf("INP status: %d\n", inp_status); 
    printf("EOF = %d\n", EOF); 

    return 0; 
} 

ここでは、そのプログラムの結果です

実際に文字が格納されているからです。

#include <stdio.h> 

int main() 
{ 
    int a; 
    int b; 
    int inp_status = 0; 

    inp_status = scanf(" %d %d", &a, &b); 
    printf("INP status: %d\n", inp_status); 
    printf("EOF = %d\n", EOF); 
    printf("Values stored: a = %d, b = %d\n", a, b); 

    return 0; 
} 

Values

値が間違って保存されているが、プログラムはまだやらせています。 scanfで結果を格納することで、実際にはエラーは発生していません。

入力の妥当性を確認する最も堅牢な方法は、this solutionのように、両方の入力を確認することです。基本的には、

if (inp_status != 2){ 
    break; 
} 

代わりの

if (inp_status == EOF){ 
    break; 
} 
関連する問題