为什么没有为scanf工作?

时间:2015-01-13 12:49:10

标签: c linux linux-device-driver

我有这个简单的代码接受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失败。有人能解释我为什么吗?

1 个答案:

答案 0 :(得分:6)

fpurge清空C级别的缓冲区,这是scanf的工作级别。

tcflush在较低级别(系统级别)执行此操作,这是read的工作级别。

scanf使用read填充自己的缓冲区。

所以在第一种情况下:用scanf清空C缓冲区效果很好,但在系统级别什么都不做。

在第二种情况下,清空系统缓冲区当然可以使用read但不能使用scanf,因为当您使用scanf时,至少在回车符中的数据是已存在于C缓冲区中。第一个scanf,读取大量数据,将它们放入缓冲区,然后使用该缓冲区返回一个char。然后你tcflush刷新系统级缓冲区但对C缓冲区什么都不做,所以下面的scanf能够在其中找到回车符。