【发布时间】:2022-01-19 14:11:19
【问题描述】:
环境:
- Windows 7 企业版 SP1
- gcc 版本 6.3.0 (MinGW.org GCC-6.3.0-1)
我是 C 语言的新手(不是编程新手)。
我正在将一个大程序迁移到 C 语言。除了这个,一切都很好。
我创建了这个小程序来重现问题:
int AAA ()
{
const char *p = "Enter to proceed.. X to Exit.. : ";
const char *ok = "OK" ;
char proceed1 ;
char proceed2 ;
printf(p) ;
fflush(stdin) ;
scanf("%c",&proceed1);
if (proceed1 == 'X'){
return 0 ; }
sleep(3) ;
fflush(stdin) ;
printf("\n%s",p) ;
scanf("%c",&proceed2);
if (proceed2 == 'X'){
return 0 ; }
printf("\n%s",ok) ;
return 0 ;
}
一切都很好,但是如果用户(错误地)在proceed1上按了两次回车键,那么proceed2的scanf会自动读取缓冲区中保留的换行符'\n'...
我尝试了所有:rewind(stdin)、fseek stdin、getchar 在第二个提示绕过问题之前,但如果用户正确地按回车键一次,让scanf 挂起。
我再说一遍,我是 C 语言的新手。我知道这个问题可以通过编写一个不接受 \n 单独的 scanf 来绕过。
但在继续之前,我在这里问这个问题:
如何彻底清除stdin 缓冲区?
【问题讨论】:
-
您曾经运行过冗长的控制台命令吗?它们在运行时确实接受并打印键盘输入。这不是质量差的标志。如果您使用 enter 进行确认 - 不要。请改用
y或输入yes来确认用户的意图。 -
"如何彻底清除标准输入缓冲区?" --> 没有标准的方法来做到这一点。将
stdin视为在不同时间传入的数据流,与stdout或其他代码发生的情况不同步。也许只是不保存空白并使用scanf(" %c",&proceed2);- 注意添加的空间。 -
这真的取决于你所说的“清除缓冲区”是什么意思。也许您的意思是“在读取块之前消耗所有存在的数据”,但也许您的意思是“读取所有数据直到下一个非空白字符”,或者您的意思可能是别的。也许您的意思是“丢弃(内部)缓冲区中的所有数据,但不再读取”。您指的是内部标准 IO 缓冲区还是终端缓冲区,还是其他一些缓存层?
-
在question 12.26b 的C FAQ list 中有一些关于这个问题的讨论。