循环中的fgetc(stdin)产生奇怪的行为

lil*_*roo 3 c fgetc

我有这个代码

while(1){
    printf("hello world !\n");
    fgetc(stdin);
}
Run Code Online (Sandbox Code Playgroud)

当它运行时,我输入这样的字母:

hello world !
a
Run Code Online (Sandbox Code Playgroud)

它忽略了下一个循环中的fgetc(stdin)并打印了两次hello world而不等待输入.

hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !
a
hello world !
hello world !
Run Code Online (Sandbox Code Playgroud)

我试过在fgetc(stdin)之前或之后放fflush(stdin),但它仍然会产生相同的行为,我做错了什么?

Ada*_*man 8

那是因为你实际上输入了两个字符:'a'和换行符.此外,由于终端通常是行缓冲的,因此只有在您按下换行符后,程序才会看到您的输入.输入更长的文本行也会提供信息.

如果要更改此行为,您有两个选择:读取整行(即所有字符到换行符或文件结尾)或将终端切换到非规范模式.如果您正在使用像文本编辑器这样的交互式终端应用程序,后者就有意义了.有关详细信息,请参见termios手册页.简而言之,您需要将MIN和TIME选项设置为零,以便在数据可用时立即从终端返回.如果确实沿着这条路走下去,请确保在退出时切换回终端,包括接收信号.

fflush() 影响输出,而不是输入.


Dan*_*umb 5

终端往往是行缓冲的,这意味着流内容可以逐行访问.

因此,当fgetc从STDIN开始读取时,它正在读取一个完整的行,其中包括结束该行的换行符.这是你正在阅读的第二个角色.

至于fflush那是用于刷新输出缓冲区而不是输入缓冲区.

所以,你想要做的是通过读取输入缓冲区直到它为空来清除输入缓冲区,或者只是显式地忽略换行符.