我想实现一个简单的代码,以在输入类型不是整数时打印错误消息。
下面是示例代码。
int num;
while (1) {
printf("Input the value of integer: ");
int result = scanf(" %d", &num);
if (result == 0) {
printf("ERROR-Not an integer.\n");
}
else if (num < 0) {
printf("ERROR- Not positive.\n");
}else{
break;
}
}
在此代码中,如果该值不是整数,则“ scanf”将询问该数字。
但是,当输入的数据不是整数时,此函数不会中断。
也许问题出在缓冲区的值。 “ fflush”将是解决方案,但我不想使用它。
答案 0 :(得分:3)
问题是您在匹配失败情况下无法清空stdin
。您正在寻找整数输入。如果用户输入的不是整数,则发生匹配失败。发生 matching failure 时,将从stdin
中提取字符,并且导致导致 matching 的字符留在输入缓冲区中(此处为stdin
) 未读-如果您尝试再次阅读而又没有再次清除stdin
的情况下再次等着您……如果您循环输入,那么您知道会发生什么。 ..
(亲爱的……我试图读取int
并失败了,但我一直尝试并且失败了-帮助?)
如何解决?
很简单,您必须在匹配失败后清空stdin
。您的工作比大多数人要好得多-您正在检查退货,但是您有一个难题要补充-当发生匹配失败时,empty_stdin()
的功能很简单。一种非常可移植且非常简单的方法是简单地提取所有字符,直到遇到换行符或EOF
,例如:
void empty_stdin(void) {
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
将示例中的所有内容放在一起,您可以:
#include <stdio.h>
void empty_stdin(void) {
int c = getchar();
while (c != '\n' && c != EOF)
c = getchar();
}
int main (void) {
int num;
while (1) {
printf("Input the value of integer: ");
int result = scanf(" %d", &num);
if (result == EOF) { /* handle ctrl+d (ctrl+z on win) */
printf (" user canceled input (manual EOF)\n");
break;
}
else if (result == 0) { /* matching failure */
printf("ERROR-Not an integer.\n");
empty_stdin(); /* remove offending characters */
}
else if (num < 0) {
printf ("ERROR- Not positive.\n");
}
else /* positive number enetered */
break;
}
return 0;
}
({@David Bowling在评论中已经说明,space
中前导" %d"
是不必要的,因为所有数字转换都消耗前导空白)
使用/输出示例
$ ./bin/scanf_empty
Input the value of integer: foo
ERROR-Not an integer.
Input the value of integer: -1
ERROR- Not positive.
Input the value of integer: bar
ERROR-Not an integer.
Input the value of integer: 1
测试手册EOF
的情况(用户按下 Ctrl + d (或 Ctrl + z 窗口)
$ ./bin/scanf_empty
Input the value of integer: user canceled input (manual EOF)
仔细检查一下,如果还有其他问题,请告诉我。
答案 1 :(得分:1)
#include <stdio.h>
int main()
{
int num;
int result;
while (printf("Please input an unsigned integer: "),
(result = scanf(" %d", &num)) != 1 || num < 0 )
{ // ║ ╚══ was successful but negative
if (result != 1) // <════════════╝ 1 conversion was requested
fputs("ERROR: Not an integer.\n", stderr); // write error messages
else fputs("ERROR: Not positive.\n", stderr); // to stderr
int ch; // the following loop *) reads garbage that might be left in stdin
while ((ch = getchar()) != '\n' && ch != EOF); // so the next scanf() won't
} // fail because of it.
printf("You entered: %d\n", num);
}
*)计划B:
scanf("%*[^\n]"); // this scanset matches all characters except newline
getchar(); // remove the newline
*)计划C:
scanf("%*[^\n]"); // this scanset matches all characters except newline
scanf("%*c"); // remove the newline
Please input an unsigned integer: foo
ERROR: Not an integer.
Please input an unsigned integer: bar
ERROR: Not an integer.
Please input an unsigned integer: -75
ERROR: Not positive.
Please input an unsigned integer: 42
You entered: 42
答案 2 :(得分:-1)
您需要在每次scanf之前/之后清除stdin。我个人以前更喜欢。
fseek(stdin,0,SEEK_END);
int num;
while (1) {
fseek(stdin, 0, SEEK_END);
printf("Input the value of integer: ");
int result = scanf_s(" %d", &num);
if (result == 0) {
printf("ERROR-Not an integer.\n");
}
else if (num < 0) {
printf("ERROR- Not positive.\n");
}
else {
break;
}
}