2014-09-28 52 views
-5

我在C中編寫了以下代碼以製作計算任意數字階乘的程序。使用isdigit驗證輸入用於階乘程序

我想添加一些驗證/錯誤處理,例如防止輸入隨機字符,浮點數或負值,所以我使用了isdigit函數。

不幸的是,有一個隱藏的問題,我不知道如何解決。當我輸入任何輸入時,即使它是正數,它也認爲它是錯誤的(即不是數字)。

#include <stdio.h> 
#include <ctype.h> 

int main() 
{ 
    char choice; 
    unsigned long long int factorial=1; 
    int counter,number; 
    for(;;) 
    { 
     printf("Please , enter a positive integer number only : "); 
     scanf("%d",&number); 
     fflush(stdin); 
     if(isdigit(number)) 
     { 
      for(counter=number;counter>1;counter--) 
      factorial*=counter; 
      printf("The factorial of number %d is %llu",number,factorial); 
     } 
     else 
     { 
      printf("\a\aError\n"); 
      continue; 
     } 
     printf("\n1-Press c or C if you want to calculate the factorial of a new number\n2-Press any key   if you want to exit the program\n "); 
     scanf("%c",&choice); 
     if(choice=='c'||choice=='C') 
     { 
      factorial=1; 
      system("cls"); 
      continue; 
     } 
     else 
     return 0; 
    } 
} 
+0

請注意12!是符合32位(無符號)整數的最大值,並且是20!是符合64位(無符號)整數的最大值。 – 2014-09-28 03:03:02

+0

除了答案,建議刪除'fflush(stdin)'並將'scanf(「%c」,&choice);'改爲'scanf(「%c」,&choice);'(增加空格)。這將消耗可選的前導空白,包括前面的行。 – chux 2014-09-28 03:28:59

回答

1

您正在使用isdigit錯誤。閱讀它的文檔以找出它的實際功能。

你大概的意思是:

if (number >= 0 && number <= 9) 

然而,你還需要檢查scanf的成功與否。如果他們鍵入某些字詞,則scanf("%d"將失敗並且不會更新number,因此在此情況下嘗試訪問number會訪問未初始化的變量。爲了解決這個問題,你既可以檢查scanf返回值,或做:

int number = -1; 
scanf("%d",&number); 

,因爲該值將保持不變,如果輸入失敗。

注意: Don't use fflush(stdin)

+0

請注意,如果平臺是Windows,'fflush(stdin)'完全定義好。如果平臺不是Windows,這是一個問題。 – 2014-09-28 02:49:12

+0

@JonathanLeffler [o rly?](http://i.imgur.com/VUfAmze.png) – 2014-09-28 02:53:35

+0

[O真的!](http://stackoverflow.com/questions/2979209/using-fflushstdin#comment31066899_2979209) - 相關鏈接MS引用的評論。 – 2014-09-28 02:55:54

0

isdigit檢查單個字符,如果這是一個十進制數字字符。 但是,你的輸入可能是25,多個字符。所以,我改變了一部分:L

char input[30]; 
for(;;) 
{ 
    printf("Please , enter a positive integer number only : "); 
    scanf("%s",input); 
    if(isdigit(input[0])) 
    { 
    number = atoi(input); 
    for(counter=number;counter>1;counter--) 

保持程序代碼段的其餘部分相同。 這裏,isdigit用於檢查輸入中的第一個字符是否是一個數字,因此是一個有效的候選項,可以通過atoi轉換爲整數值。

+0

不**使用'fflush(stdin);'來刷新輸入緩衝區 - 它不會**做你認爲它做的事。取而代之的是declare和'int c;',然後在每個scanf處理字符串輸入之後放置以下行:'do {c = getchar(); } while(c!='\ n'&& c!= EOF);'。這將刪除輸入緩衝區中的所有剩餘字符。向你自己證明。在上面的代碼中輸入:1 2 3。它會在'printf'後循環3次,永不停止。 – 2014-09-28 03:27:25