有很多方法可以正确地做到这一点:
使用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);
}
有点额外,但有一些有趣但(可能有点傻)的东西:
#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);
}
需要注意的是垃圾的消耗方式。问题在于,如果用户在没有\n 的情况下推送输入,然后我们就会陷入 getline 函数的困境(它也会耗尽内存并且需要释放输入很烦人)。所以,