当我给scanf()一个非数字作为输入时,如何继续循环?

时间:2014-12-23 08:00:29

标签: c scanf

我找到了一个简单的例子。这里它将从用户获取整数值并显示该值。 当我给出一个字符输入而不是一个整数时,我想再次跳过这个过程 询问用户输入。 为此,我在下面编写了代码,但是当我给出一个字符输入时,它将继续循环,但是在继续时它不会向用户询问输入。请为此提供解决方案。

 #include <stdio.h>

 int main()
 {
    int n;
    while(1){
            if(scanf("%d",&n)==0){
                    printf("Error:Checkyour input\n");
                    continue;
            }
            printf("the  input =%d\n",n);
    }
 }

输出如下:

  Error:Checkyour input
  Error:Checkyour input
  Error:Checkyour input
  Error:Checkyour input
  Error:Checkyour input
  Error:Checkyour input

2 个答案:

答案 0 :(得分:4)

发生这种情况是因为 ENTER 键按下[a \n]存储在输入缓冲区中并不断向提供错误的输入scanf()

对您的代码进行以下更改。

 #include<stdio.h>

 int  main()                          //add the return type.

  {
    int n;
    while(1){
            if(scanf(" %d",&n)==0){
                    while (getchar() !='\n');   //eat up all the _invalid_ input present in input buffer till newline
                    printf("Error:Check your input\n");
                    continue;
            }
            printf("the  input =%d\n",n);
    }
    return 0;                      //add the return value.

 }

关于Jonathan Leffler先生的评论,请在下面找到更优化的代码版本,同时处理EOF

 #include<stdio.h>

 int  main()

  {
    int n;
    int retval = 0;
    while(1){
            retval = scanf(" %d",&n);

            if (retval ==1)
                     printf("the  input =%d\n",n);
            else if (retval == 0)
            {
                    while (getchar() !='\n');
                    printf("Error:Check your input\n");
                    continue;
            }
            else                          //includes EOF case
                break;

    }
    return 0;

 }

答案 1 :(得分:1)

scanf()无法转换某些内容时(例如,您输入了一个字母a而不是数字),它会在输入中留下无法读取的字符,以便由另一个I / O调用处理。如果再次相同scanf(),则会再次失败,令人作呕。如果在标准输入上获得EOF,您的代码也会出错。

您有多种方法可以解决此问题:

  1. scanf()没有返回1,停在第一个错误或EOF时,你可以打破循环。
  2. 您可以使用getchar()至少读取停止输入的字符,也可以选择阅读下一个换行符(或EOF)。
  3. 您可以使用不同的scanf()格式来读取垃圾:scanf("%*[-+0-9]")例如,跳过所有不属于整数的字符。但请注意,这可能会在输入中留下--,因此它并非安全。也许scanf("%*[^ \n]")会更好。 *会抑制分配,因此不需要在某处放置读取的数据。