fgetc(stdin)在循环中产生奇怪的行为
我有这个代码
while(1){ printf("hello world !\n"); fgetc(stdin); }
当它运行时,我输入这样的字母:
hello world ! a
它忽略了下一个循环中的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 !
我试过在fgetc(stdin)之前或之后放fflush(stdin)但它仍然会产生相同的行为,我做错了什么?
终端往往是行缓冲的,这意味着流内容可以逐行访问。
因此,当fgetc
从STDIN开始读取时,它正在读取一个完整的行,其中包括结束该行的换行符。 这是你正在阅读的第二个角色。
至于fflush
,那是用于刷新输出缓冲区,而不是输入缓冲区。
所以,你想要做的是通过读取输入缓冲区直到它为空来清除输入缓冲区,或者只是显式地忽略换行符。
那是因为你实际上输入了两个字符:’a’和换行符。 此外,由于终端通常是行缓冲的,因此您的程序只有在您按下换行符后才能看到您的输入。 输入更长的文本行也会提供信息。
如果要更改此行为,您有两个选择:读取整行(即所有字符直到换行符或文件结尾)或将终端切换到非规范模式。 如果你正在使用像文本编辑器这样的交互式终端应用程序,后者是有意义的。 有关详细信息,请参见termios手册页 。 简而言之,您需要将MIN和TIME选项设置为零,以便在数据可用时立即从终端返回。 如果确实沿着这条路走下去,请确保在退出时切换回终端,包括接收信号。
fflush()
影响输出,而不影响输入。
有两个字符: a
和\n
(换行符)。 你的循环读取读取a
,然后循环并打印“hello world!”。 然后它会看到\n
并循环并打印“hello world!”。 在终端中键入+ \n
时,它将两个字符存储在stdin缓冲区中。 fgetc(stdin);
如果有可用的char,将从stdin缓冲区读取,否则它将等待,直到将char添加到缓冲区。
由于终端是行缓冲的(即,在到达换行符之前不将内容发送到程序),您有以下几种选择:
- 将整行读入缓冲区,但只占第一个字符
- 忽略换行符
- 关闭线路缓冲
要关闭行缓冲,请查看http://c-faq.com/osdep/cbreak.html和http://www.flipcode.com/archives/_kbhit_for_Linux.shtml和http://ubuntuforums.org/showthread。 php?t = 225713 (虽然我没有在这里测试过任何代码)。
你有两个字符, 'a'
和'\n'
。 这就是问题,因为fgetc只会读取一个字符。 这是文档 。
如果您只输入'\n'
– 仅按Enter键 – 您将具有预期的行为。
希望能帮助到你!