Laz*_*zer 4 c stdin flush fgets
此代码向用户询问数据,然后询问数字:
$ cat read.c
#include<stdio.h>
#include<stdlib.h>
#define MAX 10
int main() {
char* c = (char*) malloc(MAX * sizeof(char));
int num;
printf("Enter data (max: %d chars):\n", MAX);
fgets(c, MAX, stdin);
// how do I discard all that is there on STDIN here?
printf("Enter num:\n");
scanf("%d", &num);
printf("data: %s", c);
printf("num: %d\n", num);
}
$
Run Code Online (Sandbox Code Playgroud)
问题是,除了说明最大字符数的指令之外,没有任何东西可以阻止用户输入更多字符,随后将其读入num垃圾:
$ ./read
Enter data (max 10 chars):
lazer
Enter num:
5
data: lazer
num: 5
$ ./read
Enter data (max 10 chars):
lazerprofile
Enter num:
data: lazerprofnum: 134514043
$
Run Code Online (Sandbox Code Playgroud)
有没有办法丢弃通话STDIN后的所有信息fgets?
据我所知,唯一的便携式解决方案是自己耗尽缓冲:
while (getchar() != EOF);
Run Code Online (Sandbox Code Playgroud)
请注意,fflush(stdin);是不是问题的答案.
编辑:如果你只想在下一个换行符之前丢弃字符,你可以这样做:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
Run Code Online (Sandbox Code Playgroud)
scanf()函数对于用户输入来说很糟糕,除非你以某种方式知道你的输入数据是正确的(不要那么信任!),否则它对于文件输入来说并不是那么好.另外,你应该总是检查fgets()的返回值因为NULL表示EOF或其他一些例外.请记住,除非首先达到最大值,否则在fgets()数据末尾会得到用户的换行符.作为第一遍,我可能会这样做:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 10
void eat_extra(void) {
int ch;
// Eat characters until we get the newline
while ((ch = getchar()) != '\n') {
if (ch < 0)
exit(EXIT_FAILURE); // EOF!
}
}
int main() {
char c[MAX+1]; // The +1 is for the null terminator
char n[16]; // Arbitrary maximum number length is 15 plus null terminator
int num;
printf("Enter data (max: %d chars):\n", MAX);
if (fgets(c, MAX, stdin)) { // Only proceed if we actually got input
// Did we get the newline?
if (NULL == strchr(c, '\n'))
eat_extra(); // You could just exit with "Too much data!" here too
printf("Enter num:\n");
if (fgets(n, sizeof(n) - 1, stdin)) {
num = atoi(n); // You could also use sscanf() here
printf("data: %s", c);
printf("num: %d\n", num);
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)