I have written a simple programme to display the first n primes, where n is input by the user. So far, it executes fine if the user writes an integer.
However, I would like the programme to keep asking the user for a valid input if the input isn't an integer (primes(input) != 1).
I tried creating a loop (see code) to do so, but the programme enters an infinite loop.
For example, when the user inputs a letter the programme keeps displaying infinitely "How many n first primes do you want to display?" until I quit. The scanf in the loop is ignored for some reason.
Various sources gave me different explanations including a buffer problem.
What is the exact reason for this infinite loop happening, and what is the best way to get the programme to give the user as many goes as possible until input is correct?
Here is the code:
#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;
}
It really depends on your requirements.
The easiest thing to do is to check the return value from scanf
. It's basically done like this:
if(scanf("%d", &input) != 1) {
// Code for input failure
}
However, the above would accept "7asdf" which may or may not be desirable. It would also accept leading whitespace, like " 7".
If you want more fine grained control, you could always read a line and then parse it manually. Here is an idea for how it can be done:
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
}
}
The above code would not accept any other characters than digits. For instance, it would fail on leading or trailing whitespace.