【发布时间】:2014-12-03 11:58:46
【问题描述】:
我有一个函数可以从 C 中的 stdin 获取一个数字。
int io_get_num(const char *q, const size_t min, const size_t max, int * num)
{ /* Get a number from the command line */
int ret = 0;
do {
printf(q);
ret = scanf(" %d", num);
if (ret == EOF)
return EOF;
else if (ret == 0)
printf("Please provide a valid number ..\n%s", q);
else if (*num > max || *num < min)
printf("Number must be smaller than %u and larger than %u\n%s", (unsigned int)max+1, (unsigned int)min-1, q);
else
break;
/* Flushing stdin */
int ch;
while ( (ch = fgetc(stdin)) != EOF && ch != '\n' );
} while (1);
return ret;
}
它在第一次循环运行时运行良好,之后(我注意到在与 gdb 中断时)循环运行两次,除了它不等待我的输入或检查任何条件(这可能与冲洗有关流)..
我能解决这个问题吗?
【问题讨论】:
-
你为什么要完全刷新输入?你希望这段代码做什么?
-
首先,
" %d"中scanf中的那个空间的用途是什么?那里完全是多余的。其次,我没有看到任何证据表明您的循环在输入错误后重复了两次。出于某种原因,您在错误消息之后再次打印q,这可能会产生循环迭代两次的错觉,而实际上它不会发生。第三,如果min为零,您将下限范围打印为(unsigned int)min-1的想法将产生一个非常奇怪的(从用户的角度来看)输出。第四,不清楚您究竟想从这里的输入中“刷新”什么以及为什么。 -
什么是
stream?。我认为应该是stdin -
@Rustam:更正了。
-
@AndreyT:首先,为什么
" %d"是多余的?它应该强制scanf忽略空白。其次,我说我用 gcc 跟踪了代码流,所以我绝对确定它运行了两次。第三,你是对的,我更新了上面的代码。第四,这种行为试图实现非标准功能fflush。它会尝试删除 scanf 未捕获的用户空间缓冲数据(以防用户未提供有效输入来替换“%d”。尝试删除它以查看会发生什么......
标签: c validation input stream flush