2017-06-04 16 views
1

入力が整数かどうか(例えば、charや文字列ではない)をチェックしたいと思います。それが動作する理由C言語の入力タイプをチェック

#include <stdio.h> 

int main (void) 
{ 
    float a; 
    int q; 

    printf("\nInsert number\t"); 
    scanf("%f",&a); 

    q=(int)a; 
    ++q; 

    if((q - a) != 1) 
     printf("\nThe number is not an integer\n\n"); 
    else 
     printf("\nThe number is an integer\n\n"); 

    return 0; 
} 

誰かが説明していただけます: 私は(作品)は、このコードに出くわし?

+3

あなたが値として987654321を入力すると、コードが動作しそうであること。あなたがABCを打つと、それはうまくいかないでしょう。 –

+0

このコードは、入力が「a charまたはstring」であるかどうかは関係ありません。 –

+1

*常に 'scanf'の戻り値をテストします。ここでは' 1'でなければなりません。 'int'を入力してから、1の値が変換されていることを確認し、入力ストリームの次の' char'が空白であることを確認してください。 –

答えて

1

コード自体が、我々はintfloatを鋳造変更してint値がインクリメントされ、非常に単純であり:そして

q=(int)a; 
++q; 

を毎回入力として提供intがあった、(q-a)の結果であろう正確には1です。ただし、入力された(およびfloat aに保存された)入力はfloatであり、結果は1(正の数の場合)よりも大きくなります。 (q-a)で、qfloatに変換され、その結果もfloatになりますので、

です。

the C book

については、例えば参照してください。

をそれ以外の場合は、一方のオペランドがフロートである場合、他方は ではfloatに変換され、その結果のタイプです。

+2

[変換される値が表現可能な値の範囲外の場合、その動作は未定義です。](http://port70.net/~nsz/c/c11/n1570.html#6.3.1.4p2) 'float'が' int'で表現できない値を保持することは可能です。 –

+0

私はこのコードをどこにでも使用することはお勧めしません。どのように動作するのかという質問はちょうどそれを説明しました。 – syntagma

+0

非推奨について同意します。ちょうどUBがこのコードの重要な機能であると考えています(ユーザーが入力した文字列などのUBも)、したがってコメントです。 –

1

入力を取るaこれは浮動小数点数です。次に、floatintを整数qと増分値1 (q++)でキャストします。あなたが入力a = 3.4

q=(int)a; ++q;

を取るのであれば、その後、q4になります。しかし、それはaの値を変更することはできません。従ってa3.4になります。 この状態を確認した後、(q - a) != 1がtrueになります。それ以外の場合はfalseになります。あなたが入力a=3.0を取る場合

最後に、このコードは動作しません(a=3.0はフロート番号であるとして。)

2

私は(それが動作します)。このコードに出くわし:。...それが動作する理由は?

一般的には機能しません。入力を考えると

は、単一の文字Zかもしれませんあまりにも多くの失敗例scanf()aを割り当てていないとして、次のコードは、未定義の動作(UB)です。結果:(int)aはUBです。

scanf("%f",&a); 
q=(int)a; 

与えられた入力は、「123456789」は、その後、(int)aに変換intの範囲外の何かが、また、UBあるかもしれません。

aの値がINT_MAXの場合、++q;はUBです。

入力はintとして正確に表現できますが、floatではOPのコードが正しくない値です。 "0.99999999999999999999999999999"のように整数に丸められ

入力 - >1.0fはOPの検出


代替失敗します。

scanf(), fgets()テキストを読み取り、C文字列intfloatに変換すると考えるために、代わりになど、より良い、C文字列を読んintfloatません。

scanf()には、という書式の入力が含まれています。これは未知の部分です。避ける方が良いscanf()

コードでは、ユーザー入力についてさまざまなことを検出する必要があるため、行のテキストを読むには、fgets()を使用してください。その後、strtol()strtoll()strtoul()などを使用して、入力がターゲットタイプに適合するかどうかを確認します。

// Check if input fits in a `long` 
char buf[100]; 
if (fgets(buf, sizeof buf, stdin) == NULL) { 
    puts("End-of-file or input error"); 
} else { 
    char *endptr; 
    errno = 0; 
    long ivalue = strtol(buf, &endptr, 0); 
    if (buf == endptr) puts("Fail: no conversion"); 
    else if (*endptr != '\n' && *endptr != '\0') puts("Fail: Extra junk"); 
    else if (errno) puts("Fail: Overlfow"); 
    else printf("Success: %ld\n", ivalue); 
} 
1

この文:

scanf("%f",&a); 

は、あなたが知りたいことを伝えることができます。

scanf()ファミリの関数を呼び出す場合:操作が成功したことを確認するために、返された値(パラメータ値ではない)を常にチェックします。この場合

はお勧め:

if(1 != scanf("%f",&a)) 
{ // non digit entered 
    .... 
} 
関連する問題