我一直在考虑如何清除scanf
函数中的错误条目,以允许循环提示完成它们的工作。
我在这里有一个函数调用来刷新输入。如果我在2q
请求int
时输入类似void flushKeyBoard()
{
int ch; //variable to read data into
while((ch = getc(stdin)) != EOF && ch != '\n');
}
的内容,这仍然有效。
printf("Enter a value: ");
check = scanf("%f", &b);
while(check == 0)
{
printf("Invalid number entered. Please re-enter: ");
check = scanf("%f, &b");
flushKeyBoard();
}
然后我会在另一个函数中有这样的东西:
{{1}}
有更好的想法吗?有人建议fflush();但在这里使用它并不是真正的标准..
答案 0 :(得分:4)
getchar
(常见,易于理解)int c;
while ((c = getchar()) != EOF && c != '\n'); /* <note the semicolon! */
if (c == EOF) {
if (feof(stdin)) {
/* Handle stdin EOF. */
}
else {
/* Handle stdin error. */
}
}
fgets
(不太常见,不易理解)char buf[8];
while (fgets(buf, sizeof buf, stdin) != NULL) {
size_t len = strlen(buf);
/*
* Exit the loop if either EOF was encountered before '\n', or
* if '\n' is detected.
*/
if (len + 1 != sizeof(buf) || memchr(buf, '\n', len))
break;
}
if (feof(stdin)) {
/* Handle stdin EOF. */
}
else {
/* Handle stdin error. */
}
scanf
的扫描集(可能不常见,易于理解)/*
* Combining the scanset with assignment suppression (the '*' before the
* scanset) will return EOF on EOF/error and 0 if '\n' was read.
*/
if (scanf("%*[^\n]") == EOF) {
if (feof(stdin)) {
// Handle stdin EOF.
}
else {
// Handle stdin error.
}
}
getchar(); // Flush the '\n'.
getline
(可能不常见,很难)char *buf = NULL;
size_t bufsize = 0;
ssize_t len;
/* getline() will stop reading on '\n' or EOF. */
len = getline(&buf, &bufsize, stdin);
/* No bytes read and EOF encountered, or there was an error. */
if (len == -1) {
if (feof(stdin)) {
/* Handle stdin EOF. */
}
else if (ferror(stdin)) {
/* Handle stdin error. */
}
else {
/* Handle errno error, if desired. */
}
/*
* The value of "buf" is indeterminate here, so you likely
* just want to return from the function/program at this point
* rather than continuing and potentially freeing an invalid
* buffer.
*/
}
free(buf);
当然,所有这些方法都假设您希望处理EOF /错误发生的事情与\n
不同,甚至可能三个都是单独的情况。例如,通过将上述代码段中的一个放入自包含函数中,如果读取了0
,则可能会返回\n
或者在EOF /错误时返回EOF
,甚至0
在\n
上,EOF
在EOF上,1
出错。
值得注意的事情:
getchar
和fgets
方法是100%跨平台的。我更喜欢getchar
方法。getline
方法也不是跨平台的:它主要在GNU / Linux和其他一些POSIX操作系统上实现;目前不包括Windows。一旦你掌握了管理内存和使用指针的经验,自己编写一个并不是非常困难,但是自从编写getline
的实现以来,你最好使用前两种方法中的一种。最终可能最终会使用fgetc
或fgets
(fgetc(stdin)
和getchar()
的行为相同)。答案 1 :(得分:0)
您可以使用:
fscanf(stdin, "%*[^\n]%*c");
答案 2 :(得分:0)
有几种方法可以做到这一点。实际上,你要做的是消耗一行文字直到\ n字符(或EOF)。为了做到这一点,你应该使用sscanf(或fscanf。)
sscanf("%*[^\n]\n");
这使用正则表达式[^ \ n] * \ n(任意数量的字符不是\ n,后跟一个\ n)并使用与之匹配的所有内容。
编辑:因为我愚蠢而忘记了scanf正则表达式使用的语法略有不同。