2016-11-09 73 views
3

我从来没有用C编写过程,现在我必须编写小代码。程序非常简单 - 我想添加两个整数。 但是,当我试图检查给定的输入是否是一个数字,并且第一个scanf返回0时,第二个返回0也不等待输入。 代码:Scanf返回0而无需等待输入

int main() 
{ 
    int a = 0; 
    int b = 0; 
    printf("Number a:\n"); 
    if (scanf("%d", &a) != 1) 
    { 
     printf("Not a number. a=0!\n"); 
     a = 0; 
    } 
    printf("Number b:\n"); 
    if (scanf("%d", &b) != 1) 
    { 
     printf("Not a number. b=0!\n"); 
     b = 0; 
    } 
    printf("%d\n", a+b); 
    return 0; 
} 
+0

UV用于检查输入函数'...!= 1'的返回值。太多的问题源于不做第一步。至少这篇文章做了这个重要的一步。 – chux

回答

1

这是因为,一旦第一scanf()失败了,这是匹配失败可能是因为和这引起了匹配失败的输入,保持输入缓冲区内,等待明年的呼叫消耗。

因此,为了scanf()下次调用也尽量消耗居住在立即输入缓冲器一样无效输入,无需等待明确的外部用户输入的输入缓冲区不是空的。

解决方案:scanf()第一输入失败后,必须清理输入缓冲区,为一个简单的例子,像while (getchar() != '\n');应该做的工作。

+0

可能还想检查换行符。 – dbush

+3

你需要一个更复杂的'while'循环,最好包装在一个函数中。直到EOF在输入缓冲区为空时不会停止读取,它将被阻止。它只会在EOF处结束,这意味着用户输入了ctrl-d(Unix shell)或ctrl-Z(Windows终端)或类似的东西。 – hyde

+0

@hyde是的,基本上你是对的,我只是想描述这个想法,就是这样。 –

0

这是因为输入和输出在C中不同步。程序可以在用户输入后输出一些行,而输入没有被读取。尝试运行这段代码:

char token; 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 1\n"); 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 2\n"); 

scanf("%c", &token); 
printf("%c\n", token); 
printf("line 3\n"); 

输入ABC在一行

你可以想象这就像有两个分开的控制台,一个用于输入,另一个用于输出。


例如要输入ASDab。在这种情况下,第一个scanf将找不到任何数字,并返回0.但它也不会从输入中读取任何内容。因此,第二个scanf也会看到asd

清除输入,如果a不是一个数字,你应该输入该行的所有剩余字符,直到'\n'(看@ Sourav的解决方案)

1

未能转换为数字的输入第一个fscanf()仍在标准输入的缓冲区中,并导致第二个fscanf()也失败。尝试丢弃违规输入并重新提示用户:

#include <stdio.h> 

int main(void) { 
    int a = 0; 
    int b = 0; 
    int c; 
    printf("Number a:\n"); 
    while (scanf("%d", &a) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      exit(1); 
    } 
    printf("Number b:\n"); 
    while (scanf("%d", &b) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      exit(1); 
    } 
    printf("%d\n", a + b); 
    return 0; 
} 

因式分解与效用函数的代码使得它更清晰:

#include <stdio.h> 

int get_number(const char *prompt, int *valp) { 
    printf("%s:\n", prompt); 
    while (scanf("%d", valp) != 1) { 
     printf("Not a number, try again:\n"); 
     while ((c = getchar()) != EOF && c != '\n') 
      continue; 
     if (c == EOF) 
      return 0; 
    } 
    return 1; 
} 

int main(void) { 
    int a, b; 

    if (!get_number("Number a", &a) || !get_number("Number b", &b)) { 
     return 1; 
    } 
    printf("%d\n", a + b); 
    return 0; 
} 
0

你可以做使用字符串同样的事情,不与scanf函数的问题。只需将用户输入作为字符串并将其转换为整数。然后将字符串转换回整数来检查它们是否相同。如果它们相同,则将a和b视为整数,如果不是,则执行您的操作(您将需要包含string.h)。这里是工作代码:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
int a; 
int b; 
char str1[100]; 
char str2[100]; 

printf("Number a:\n"); 
scanf("%s", &str1); //take input as a string 
a = atoi(str1); //convert string to integer 
snprintf(str2, 100, "%d", a); //convert integer back to string 

//if the integer converted to string is not the same as the string converted to integer 
if (strcmp(str1, str2)!= 0) 
{ 
printf("Not a number. a=0!\n"); 
a = 0; 
} 
printf("Number b:\n"); 
scanf("%s", &str1); 
b = atoi(str1); 
snprintf(str2, 100, "%d", b); 

if (strcmp(str1, str2)!= 0) 
{ 
printf("Not a number. b=0!\n"); 
b = 0; 
} 
printf("%d\n", a+b); 

return(0); 
}