2012-08-04 65 views
2

我在我的代码下面遇到问题。当我输入任何整数,即(0-9),那么它是确定的。但是,当我输入其他字符如AB或任何其他字母scanf()失败。然后它不会等待任何进一步的输入。为什么scanf在一次失败后不等待用户输入?

我附上了一个代码片段。我非常需要仅使用C标准库的错误处理。

#include <stdio.h> 

int main() 
{ 
    int choice; 
    while(1) 
    { 
     printf("Enter your choice: "); 
     if(0 == scanf("%d", &choice)) 
      { 
       printf("Some error occured\n"); 
       //break;/*I did not want to break this loop as I use this to show menu*/ 
      } 

     switch(choice) 
     { 
         case 0:printf("Case 0\n");break; 
         case 1:printf("Case 1\n");break; 
         case 2:printf("Case 2\n");break; 
         case 3:printf("Case 3\n");break; 
         case 4:printf("Case 4\n");break; 
         case 5:printf("Case 5\n");break; 
         case 6:printf("Case 6\n");break; 
         case 7:printf("Case 7\n");break; 
         case 8:printf("Case 8\n");break; 
         case 9:printf("Case 9\n");break; 
         default:printf("Default case\n");break; 

     } 
    } 
} 

更清楚的问题是:为什么在失败后等待?

回答

3

使用scanf,如果给定的输入与格式规范不匹配,则输入不会被消耗并保留在输入缓冲区中。换句话说,不匹配的字符永远不会被读取。

因此,当你输入时,例如一个a字符,您的代码将无限循环,因为scanf继续在同一个字符上失败。

scanf返回一个错误,你需要摆脱违规字符(s)。

你无法知道有多少字符将被输入,但一个简单的方法来消耗任何违规的字符是尝试读取字符串时scanf函数失败:

char junkChars[256]; 

printf("Enter your choice: "); 
if (scanf("%d", &choice) == 0) 
{ 
    printf("Some error occured\n"); 
    scanf("%s", junkChars); 
} 

这将清除输入缓冲区,但依赖于上限。如果用户键入比256个字符,则scanf将在下一次迭代中继续使用它们。

很明显,这是一个丑陋的解决方案,但由于这个原因,scanf并不是一个很好的输入机制。最好使用fgets将输入行作为字符串,然后自己控制该字符串的解析。

+0

这工作正常,但是C库提供了一些设施来清除输入缓冲区。就像它们为输出缓冲区提供像fflush()一样的工具。 – rajesh6115 2012-08-04 02:44:13

+0

不,没有标准的工具来清除输入缓冲区(尽管有些实现可能提供它)。只要阅读输入,例如使用fgets()。这只是一个像fflush()一样的函数调用。 – nos 2012-08-04 02:48:02

+0

谢谢你的回答... – rajesh6115 2012-08-04 02:53:22

0

这是设计。

请勿使用中断,请使用继续

+0

我想知道为什么不等待我的输入进一步,我如何管理错误,以便我可以再次输入。 – rajesh6115 2012-08-04 02:29:00

+0

它为什么要等待?当你按Enter键时,你正在读取字符串。如果出现错误,您需要决定是否要重试或中止程序。 – 2012-08-04 02:33:43