循环直到用户在 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
}
}
以上代码不接受除数字以外的任何其他字符。例如,它会在前导或尾随空格上失败。
我写了一个简单的程序来显示前 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
}
}
以上代码不接受除数字以外的任何其他字符。例如,它会在前导或尾随空格上失败。