为什么isEOF不起作用?

时间:2014-10-22 12:38:04

标签: haskell io stream eof

这是最小的完整示例:

import Control.Monad
import System.IO

loop :: IO ()
loop =
    do line <- getLine
       putStrLn line
       eof  <- isEOF
       unless eof loop

main = loop

该程序应该读取一行,将其打印出来,如果有文件末尾则停止播放&#39; stdin中的字符。它根本不会离开循环。

如果我在eof <- isEOF之前放置putStrLn line,程序会表现得非常奇怪(试试吧!)。我根本无法理解:putStrLn如何影响输入流以及为什么程序在文件结束时终止程序&#39}。字符流入(使用 Ctrl + D )?


eof <- isEOFputStrLn line之前的行为描述:

  

输入一行后,程序不会打印输入的行,但需要更多输入。随着它获得更多输入,它开始打印先前输入的行。这是测试日志:

foo
boo
output: foo
bar
output: boo
baz
output: bar
< here I press Ctrl-D >
output: baz

来源:

import Control.Monad
import System.IO

loop :: IO ()
loop =
    do line <- getLine
       eof  <- isEOF
       putStrLn $ "output: " ++ line
       unless eof loop

main =
    do hSetBuffering stdin LineBuffering
       loop

1 个答案:

答案 0 :(得分:4)

来自http://lambda.haskell.org/platform/doc/current/ghc-doc/libraries/haskell2010-1.1.1.0/System-IO.html#g:11

  

注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取以确定是否还有其他数据需要读取。

putStrLn不会影响isEOF,但isEOF会阻止程序在有更多字符可用之前到达putStrLn,或者您有实际上按了^D

所以你永远不要使用hIsEOF / isEOF,直到你准备好阅读更多字符的程序中,如果有的话。