2016-10-03 15 views
0

私はisdigit機能の私の理解をテストするには、この短いコードを書いた:Isdigit機能が正常に動作しないのはなぜですか?

int inChar; 
printf("enter input:"); 
scanf(" %d", &inChar); 

if (isdigit(inChar)) 
    printf("Your input was a number"); 
else 
    printf("Your input was not a number.\n"); 

私はこのプログラムをテストし、私は番号を入力すると、Cは(あなたの入力が数値ではありませんでした。)else文を返します。したがって、数字や文字を入力しても、プログラムはelse文を返します。

これはなぜですか?

+1

isdigitはintではなくchar型で動作します。%cで読み取る – stark

+0

Cライブラリ関数void isdigit(int c)は、渡された文字が小数点文字かどうかを調べます。 –

+0

@stark詳細: 'isdigit(int)'は 'int'引数を受け取り、' [0 ... UCHAR_MAX] 'と' EOF'の範囲で動作します。 ''%c "'で読み込まれた値は 'isdigit()'に渡され、負である( 'EOF'ではなく)場合はUBです。 – chux

答えて

2

isdigit()か否かをチェックchar値unsigned charを変換して、それに渡された単一文字。 したがって、int値を直接渡すことはできず、動作することを期待することはできません。

マンisdigit()は言う:

isdigit() 
      checks for a digit (0 through 9). 

一桁をチェックするには、変更することができます。

char inChar; 
printf("enter input:"); 
scanf(" %c", &inChar); 

if (isdigit((unsigned char)inChar)) { 
    printf("Your input was a number"); 
} 
else { 
printf("Your input was not a number.\n"); 
} 

を使用すると、配列(番号を含む文字列)を持っているなら、あなたは、ループを使用することができます。

+3

intを正しく渡すことができます。 'isdigit'は実際に' int'型を期待しています。問題は、 '%d 'で読み取られた数字がASCII値ではなく数値を与えることです。 – Lundin

+2

プロトタイプが持っているので、intを直接渡すことは有効です。しかし、isdigit()は値がunsigned charで表現可能であることを要求します。だから、それをunsigned charに変換する一般化された解決策が必要です。 (そうでなければ、渡された値がその要件を満たしていることを確認する必要があります)。そう、はい、あなたは正しいですが(注意が必要です)。 – usr

+0

詳細: '' isdigit() 'は、値が' unsigned char'または 'EOF'で表現可能であることを要求します。 – chux

2

この関数の目的は、文字を分類することです('3'など)。 %dを使用して読み取られたもので実行することは意味がありません。

%cを使用して1つのcharを読む必要があります。読み込みに成功したことを確認してください。

1

Cライブラリ関数void isdigit(int c)は、渡された文字が小数点文字かどうかを確認します。

あなたはひどくたいあなたは、次のコードは、期待される結果が得られたこのよう

int inChar = '2'; 

にはinitができintでそれをしよう。

int main() 
{ 
    char inChar; 
    printf("enter input:"); 
    scanf(" %c", &inChar); 
    if (isdigit(inChar)) 
     printf("Your input was a number. \n"); 
    else 
     printf("Your input was not a number.\n"); 
    return 0; 
} 

出力:

vinay-1> ./a.out 
enter input:1 
Your input was a number 
+0

これで問題はありません。すべてのコメントを削除することができます。このコメントも数分で削除します。 –

0

isdigitがフォーマット

int isdigit(int c); // 7.4.1.5 

を持っているにもかかわらず、それは実際に文字を期待しています。シンボルテーブルの値と同じです。

scanf("%d")intを読むと、生の整数値が得られます(例:1)。しかしisdigitはシンボル値'1'を必要とし、これはほとんどのシンボルテーブルの生の値49です。 isdigitの全目的は、入力がASCII数字かどうかを確認することです。

問題を解決するには、文字型を使用することをお勧めします。または、isdigit(inChar+'0')を渡して、生の値をシンボルテーブルの値に変換します。

+1

'unsigned char'の値が' isdigit(inChar + '0') 'でオーバーフローするのはどうですか? UBじゃない? –

+0

@AndrewHenleあなたの例ではオーバーフローはありません。 'inChar'にすでに' '0''が入っているのでしょうか?それは明らかにバグでしょう。鍵は、あなたがしていることを実際に知ることです。 – Lundin

+1

ユーザが '-151235'を入力するとどうなりますか? '' 0 ''を追加すると、 '' unsigned char''として表現できない値が生成され、** 7.4の文字単位でUBを呼び出します。 **:すべての場合、引数は 'int 'の値は、 ' unsigned char'で表現されなければならず、また、 'EOF'マクロの値と等しくなければならない。 引数に他の値がある場合、動作は未定義です* –

関連する問題