这是最小的完整示例:
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 <- isEOF
在putStrLn 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
答案 0 :(得分:4)
注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取以确定是否还有其他数据需要读取。
putStrLn
不会影响isEOF
,但isEOF
会阻止程序在有更多字符可用之前到达putStrLn
,或者您有实际上按了^D
。
所以你永远不要使用hIsEOF
/ isEOF
,直到你准备好阅读更多字符的程序中,如果有的话。