为什么tcflush不能用于scanf?

Emp*_*uin 4 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);
Run Code Online (Sandbox Code Playgroud)

我明白为什么这只会接受2个字符,因为第二个scanf接受回车.但是,如果__fpurge(stdin);在每个scanf之间使用代码,则代码按预期工作.但是,如果我使用read(STDIN_FILENO,&a,1);而不是scanf,它不起作用.对于read(),只能tcflush(STDIN_FILENO,TCIOFLUSH);工作,但它与scanf失败.有人能解释一下为什么吗?

Jea*_*nès 6

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

tcflush是在较低级别(系统级别),这是工作的级别read.

scanf用于read填充自己的缓冲区.

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

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

  • 使用`fread`时,从C缓冲区读取数据.如果这个是空的,那么使用`read`从系统重新填充.当你把'fwrite`数据写入C缓冲区时.如果这个已满,则使用`write`将数据刷新到系统.只需考虑一下你管理口袋里的钱和你的银行账户的方式(口袋= c-buffer,bank = system;口袋满满的银行,口袋空,从银行填写)...... (2认同)