2013-11-28 56 views
2

请考虑以下简单的C程序。如何测试输入是否正常

//C test 

#include<stdio.h> 

int main() 
{ 
    int a, b, c; 

    printf("Enter two numbers to add\n"); 
    scanf("%d%d",&a,&b); 

    c = a + b; 
    printf("Sum of entered numbers = %d\n",c); 
    return 0; 
} 

你如何检查输入的值实际上是在一些合理的范围内的两个整数?目前,如果您只输入“a”,然后返回,您将得到输出“输入数字总和= 32767”。

我想阻止错误输入的示例。

  1. 2 3 4(错误的号码号码)
  2. 苹果(非数字)
  3. 11111111111111111111111111 1111111111111111111111111111111111111(数字超出范围)

或者我应该使用fgetssscanf或甚至strtol

回答

1

用户输入是邪恶的。每解析:

(optional whitespace)[decimal int][whitespace][decimal int](optional whitespace) 

strtol()和家人有更好的错误处理比scanf()
Coda:最好能够在帮手功能中处理用户输入。分为两部分:I/O和解析。

#include <ctype.h> 
#include <errno.h> 
#include <limits.h> 
#include <stdio.h> 
#include <stdlib.h> 

// return 1 (success), -1 (EOF/IOError) or 0 (conversion failure) 
int Readint(const char *prompt, int *dest, size_t n) { 
    char buf[n * 21 * 2]; // big enough for `n` 64-bit int and then 2x 

    fputs(prompt, stdout); // do not use printf here to avoid UB 
    fflush(stdout); // per @OP suggestion 
    if (fgets(buf, sizeof buf, stdin) == NULL) { 
    return -1; 
    } 
    const char *p = buf; 

    while (n-- > 0) { 
    char *endptr; 
    errno = 0; 
    long l = strtol(p, &endptr, 10); 
    if (errno || (p == endptr) || (l < INT_MIN) || (l > INT_MAX)) { 
     return 0; 
    } 
    *dest++ = (int) l; 
    p = endptr; 
    } 

    // Trailing whitespace OK 
    while (isspace((unsigned char) *p)) p++; 
    // Still more text 
    if (*p) return 0; 
    return 1; 
} 

int main() { // for testing 
    int Result; 
    do { 
    int dest[2] = { -1 }; 
    Result = Readint("Enter two numbers to add\n", dest, 2); 
    printf("%d %d %d\n", Result, dest[0], dest[1]); 
    } while (Result >= 0); 
    return 0; 
} 
+0

谢谢。也许在'fputs()'之后加一个'fflush()',以防在提示符末尾不包含'\ n')?另外,如果你输入一个200位数的数字,你可以从你的代码中得到多个输出。我不知道为什么。最后,有没有保证INT_MAX marshall

+0

@marshall 200位是由于'buf [n * 21 * 2]'引起的。根据需要调整大小。一个_could_动态增长'buf'应该'fgets()'得到没有'\ n'的输入。但这主要是IO问题,你的文章就是这样,但更多的是解析文章。 – chux

+0

@marshall INT_MAX <= LONG_MAX肯定是对的。 '(l INT_MAX)'是否应该'long'的范围比'int'更宽。 – chux

2

您可以使用诸如:

if(scanf("%d%d",&a,&b) == 2) 
{ 
    //two integer values has been read successfully 
    //do your stuff here 
} 
else 
{ 
    //Wrong input 
} 
+0

2 3 4未报即由于某种原因,你的代码输入错误,111111111111111111111111111111 111111111111111111111111111111111111给出了答案-2。 – marshall

0

一个简单的办法是,

int a=0, b=0, c=0; 

初始化他们0

此外,通过Midhun建议的检查是好检查是否存在是两个输入。

1

您可以使用下面的宏

#define SCAN_ONEENTRY_WITHCHECK(FORM,X,COND) \ 
do {\ 
    char tmp;\ 
    while(((scanf(" "FORM"%c",X,&tmp)!=2 || !isspace(tmp)) && !scanf("%*[^\n]"))\ 
      || !(COND)) {\ 
     printf("Invalid input, please enter again: ");\ 
    }\ 
} while(0) 

,你在主

int main() 

{ 
    int a, b, c; 

    printf("Input first integer, valid choice between 0 and 10: "); 
    SCAN_ONEENTRY_WITHCHECK("%d",&a,(a>=0 && a<=10)); 

    printf("Input second integer, valid choice between 0 and 10: "); 
    SCAN_ONEENTRY_WITHCHECK("%d",&b,(b>=0 && b<=10)); 

    c = a + b; 
    printf("Sum of entered numbers = %d\n",c); 
    return 0; 

} 

调用它以这种方式更详细的关于这个宏,请参阅:Common macro to read input data and check its validity

2

而且你可以这样做,以防止第二个数字后的任何东西

int a,b; 
char c; 
if(scanf("%d%d%c", &a, &b, &c) == 3) { 
    if (c == '\n') { 
     puts("good"); 
    } 
} else { 
    puts("bad"); 
} 
    return 0; 
} 
0

你可以测试这一个。

#include <stdio.h> 

int main(void) 
{ 
    int a, b, c; 

    printf("Enter two numbers to add\n"); 
    scanf("%d%d",&a,&b); 

    if(scanf("%d%d",&a,&b) == 2) 
    { 
     c = a + b; 
     printf("Sum of entered numbers = %d\n",c); 
    } 
    return 0; 
} 
+0

谢谢,但这与Midhun的代码有相同的问题。 – marshall

相关问题