scanf如何确定是否阻止?

时间:2015-05-23 06:19:40

标签: c scanf io-redirection

当我从命令行使用stdin命令将文件重定向到MyProgram < cl.txt时,scanf并没有等我按Enter键。

但是当我在程序中使用scanf而没有这样做时,它会一直阻塞,直到按下回车键。

它究竟是如何确定的?在遇到\n之前,它是否继续阅读流?还是真的等我按一个键?

当我没有写任何内容并按Enter键时,它也不会停止阻止并继续询问。我真的很困惑。

3 个答案:

答案 0 :(得分:6)

scanf只是从其输入流中读取。如果输入流是管道,并且该管道的另一端与tty相关联(如果您通过按键盘上的键以交互方式输入数据,通常就是这种情况),scanf将在读取数据后立即返回完成其格式字符串(或无法匹配)。然而,tty,如果它处于熟模式(这是默认模式,除非你努力将tty放入原始模式,你应该假设它正在烹饪你输入的内容),不会将任何数据写入管道直到你回来。

换句话说,这不是你的scanf阻塞。 (好吧,它阻塞,但它不是经验延迟的来源。)相反,tty驱动程序在等待你将任何数据传递给你的程序之前点击返回。

答案 1 :(得分:5)

  

是否继续阅读流,直到&#39; \ n&#39;遇到了什么?

通常stdin处于线缓冲模式(_IOLBF,请参阅setvbuf)。只要缓冲区为空,stdin就会等待输入一个全新的行,即等到你按Enter键并将\n插入缓冲区:

  

On Input,当请求输入操作且缓冲区为空时,缓冲区将填充到下一个换行符。

注意:控制台(终端)通常自己实现缓冲,并且在您按Enter键之前不会向流发送任何数据 - 这允许您编辑数据(如使用删除和退格键)在将它们发送到应用程序之前。因此,即使stdin方没有缓冲(例如,当您执行setvbuf(stdin, NULL, _IONBF, 0)时),scanf可能仍会等到按下Enter键。

答案 2 :(得分:2)

当您调用scanf时,它会立即等待输入。在第一个示例中,输入以“cl.txt”的形式提供。在第二个示例中,在按下某个键之前不会提供任何输入。同步IO将阻塞其正在执行的线程,直到它收到输入。