2014-09-28 54 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