我有这个简单的代码接受3个字符,:
char a,b,c;
scanf("%c",&a);
scanf("%c",&b);
scanf("%c",&c);
printf("%c",a);
printf("%c",b);
printf("%c",c);
我理解为什么这只会接受2个字符,因为第二个scanf接受回车符。但是,如果在每个scanf之间使用__fpurge(stdin);
,则代码按预期工作。但是如果我使用read(STDIN_FILENO,&a,1);
而不是scanf,它就不起作用。对于read()
,只有tcflush(STDIN_FILENO,TCIOFLUSH);
可以正常工作,但它与scanf失败。有人能解释我为什么吗?
答案 0 :(得分:6)
fpurge
清空C级别的缓冲区,这是scanf
的工作级别。
tcflush
在较低级别(系统级别)执行此操作,这是read
的工作级别。
scanf
使用read
填充自己的缓冲区。
所以在第一种情况下:用scanf
清空C缓冲区效果很好,但在系统级别什么都不做。
在第二种情况下,清空系统缓冲区当然可以使用read
但不能使用scanf
,因为当您使用scanf
时,至少在回车符中的数据是已存在于C缓冲区中。第一个scanf
,读取大量数据,将它们放入缓冲区,然后使用该缓冲区返回一个char。然后你tcflush
刷新系统级缓冲区但对C缓冲区什么都不做,所以下面的scanf
能够在其中找到回车符。