循环直到用户在 C 中输入正确

Loop until user input is correct in C

我写了一个简单的程序来显示前 n 个素数,其中 n 是由用户输入的。到目前为止,如果用户写入一个整数,它执行得很好。

但是,如果输入不是整数 (primes(input) != 1),我希望程序继续询问用户输入是否有效。

我尝试创建一个循环(参见代码)来执行此操作,但程序进入了无限循环。

例如,当用户输入一个字母时,程序会一直无限显示“你想显示多少n个第一素数?”直到我退出。由于某种原因,循环中的scanf被忽略了。

各种来源给了我不同的解释,包括缓冲区问题。

发生这种无限循环的确切原因是什么?让程序为用户提供尽可能多的循环直到输入正确的最佳方法是什么?

代码如下:

#include <stdio.h>

int primes(int input);

int main(void)
{

  int input;
  
  printf("How many n first primes do you want to display? ");
  scanf("%d", &input);

    while(primes(input) != 1)
    {
    printf("How many n first primes do you want to display? ");
    scanf("%d", &input);
    }

  return 0;
}

int primes(int input)
{
  
  int count1 = 0, count2 = 0, b = 1, n = 2;
  
  if(input>=1) 
  {

      while (count1 < input)  
      { 
        b = 1;
        count2 = 0;
        while (b <= n)
        {
        
          if (n%b == 0)
          {

        count2++;
       
          }
         
          b++;
        
        }   
        
        if(count2 == 2)   
        {
        
          printf("%d\n",n);
          count1++;
         
        }
         
        n++;
          
      }

  return 1;
  
  }

  return 0;
              
}   

这真的取决于您的要求。

最简单的方法是检查 scanf 中的 return 值。基本上是这样完成的:

if(scanf("%d", &input) != 1) {
    // Code for input failure
}

但是,以上将接受“7asdf”,这可能是可取的,也可能不是可取的。它还会接受前导空格,例如“ 7”。

如果你想要更细粒度的控制,你总是可以读取一行然后手动解析它。这是如何完成的想法:

char buf[100];
if( !fgets(buf, sizeof buf, stdin)) { // Read one line as input
    // Handle input error
}

buffer[strcspn(buffer, "\n")] = 0;  // Remove newline character because fgets leaves it there

int len = strlen(buffer);

for(int i=0; i<len; i++) {
    if( !isdigit((unsigned char)buffer[i]) ) {
        // Handle error
    }
}

以上代码不接受除数字以外的任何其他字符。例如,它会在前导或尾随空格上失败。