There are many ways to do this correctly:
Using scanf:
#include <stdio.h>
#include <stdlib.h>
int get_num() {
int i;
printf("Enter a number between 3 and 69: ");
fflush(stdout);
if (scanf("%d", &i) != 1) {
fprintf(stderr, "incorrect number of arguments, we need exactly one number (between 3 and 69)\n");
return -1;
}
if( i < 3 || i > 69 ) {
fprintf(stderr, "oops the number must be between [3, 69]\n");
return -2;
}
return i;
}
void eat_trash() {
int c;
while((c = getchar())!= '\n' && c !=EOF);
}
int main() {
int value;
while ((value = get_num()) <= 0 ) {
eat_trash();
}
printf("Got: %d\n", value);
}
A little extra but has interesting but (maybe slightly silly) things:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int stdin_copy;
int get_num() {
int i, rv = 0;
static int err_count = 0;
char *input = NULL;
size_t len = 0;
printf("Enter a number between 3 and 69: ");
fflush(stdout);
// gets a line (allocates memory we have to free)
rv = getline(&input, &len, stdin);
if ( rv > 3 ) {
err_count++; // see if we have a lot of garbage incoming
free(input);
if (err_count < 3 ) {
fprintf(stderr, "a number between 3 and 9 only needs two characters, try again. (%d tries left)\n", 3 - err_count);
return -3;
}
// just stop dealing with this silly user.
fprintf(stderr, "really? okay bye!\n");
exit(127);
}
rv = sscanf(input, "%d", &i);
free(input);
if (rv != 1) {
fprintf(stderr, "incorrect number of arguments, we need exactly one number (between 3 and 69)\n");
return -1;
}
if( i < 3 || i > 69 ) {
fprintf(stderr, "oops the number must be between [3, 69]\n");
return -2;
}
return i;
}
void eat_trash() {
fclose(stdin);
stdin = fdopen(stdin_copy, "r");
stdin_copy = dup(fileno(stdin));
}
int main() {
int value;
stdin_copy = dup(0);
while ((value = get_num()) <= 0 ) {
eat_trash();
}
printf("Got: %d\n", value);
}
The thing to note is the way trash is being consumed. The trouble with this is what happens if user pushes an input without \n
and then we are stuck in the way getline functions (also it can use up memory and that needing to free the input is annoying). So,