此代码应读取正数,如果用户输入非数字值,则再次要求他输入数字并等待输入再次检查,直到输入数字
do
{
printf("Enter a positive number: ");
}
while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) ) ;
但实际上在输入非数字时它会继续执行while循环体,而不会等待检查while循环的条件while(scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0)
将条件编辑为
时int clean_stdin()
{
while (getchar()!='\n');
return 1;
}
do
{
printf("Enter a positive number: ");
}
while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) && clean_stdin() ) ;
它以正确的方式执行,但我不明白为什么我们需要添加getchar()
,尽管我们已经在条件中使用scanf()
答案 0 :(得分:2)
考虑使用fgets收集输入。任何无效输入都已从输入流中删除,这使得再次尝试变得更加简单 根据需要使用sscanf或其他方法解析输入。
char input[40] = "";
int valid = 0;
int n = 0;
do {
printf ( "Enter a positive integer\n");
if ( fgets ( input, sizeof ( input), stdin)) {
int last = 0;
if ( 1 == ( valid = sscanf ( input, "%d%n", &n, &last))) {
if ( n < 0 || input[last] != '\n') {
valid = 0;//reset if negative or last is not newline
}
}
}
else {
fprintf ( stderr, "problem getting input from fgets\n");
return 0;
}
} while ( valid != 1);
答案 1 :(得分:2)
当scanf("%d%c", ...
遇到非数字输入时,"%d"
会导致扫描停止,并且违规字符将保留在stdin
中以用于下一个输入功能。 "%c"
没有机会阅读该非数字字符。
如果代码使用相同的stdin
重新读取scanf("%d%c", ...
,则结果相同。删除非数字输入需要一些其他方式。 getchar()
,getch()
等会读取任意一个字符。
答案 2 :(得分:0)
因为具有大多数说明符的scanf()
会忽略空格,并且如果缓冲区中遗留了scanf()
,则需要在再次调用'\n'
之前收集它们。如果你没有收集它们(并立即丢弃它们),那么scanf()
将在下次通话时立即返回。
答案 3 :(得分:0)
请参阅此代码
#include <stdio.h>
int
main(int argc, char* argv[]) {
char c = 0;
scanf("%c", &c);
printf("%c\n", c);
scanf("%c", &c);
printf("%c\n", c);
return 0;
}
如果您键入两个或三个字符,则第二次调用scanf不会起到干扰。并且getch()不是标准的。你也不应该调用getchar(),因为它可能会阻塞。 您可以使用fseek 。
使用fseek的Hack只适用于Windows。 : - (
#include <stdio.h>
int
main(int argc, char* argv[]) {
char c = 0;
scanf("%c", &c);
printf("%c\n", c);
fseek(stdin, 0, SEEK_END);
scanf("%c", &c);
printf("%c\n", c);
return 0;
}
#include <stdio.h>
int
main(int argc, char* argv[]) {
char buf[BUFSIZ];
char c = 0;
scanf("%c", &c);
printf("%c\n", c);
while (!feof(stdin) && getchar() != '\n');
scanf("%c", &c);
printf("%c\n", c);
return 0;
}
这适用于Windows&amp; Linux的