为什么EOF不起作用? [英] Why isEOF doesn't work?
问题描述
import Control.Monad
import System.IO
loop :: IO()
loop =
do line< - getLine
putStrLn line
eof< - isEOF
除非eof loop
main = loop
这个程序应该是读一行,打印出来,如果 stdin
中存在'文件结尾'字符,请停止。它完全不会离开循环。
如果我在<$ c之前放置 eof< - isEOF
$ c> putStrLn行该程序的行为非常奇怪(试一试!)。我无法得到它:如何 putStrLn
可能会影响输入流,为什么当我将'文件结尾'字符放入流中时程序不终止( Ctrl + D )?
当 eof< - isEOF
在 putStrLn行
之前:
$ b
之后输入一行,程序不打印输入的行,但需要更多的输入。当它获得更多输入时,它开始打印先前输入的行。这是测试的日志:
foo
boo
输出:foo
bar
输出:boo
baz
输出:bar
<在这里我按Ctrl-D>
输出:baz
来源:
import Control.Monad
import System.IO
loop :: IO()
loop =
do line < - getLine
eof< - isEOF
putStrLn $输出:++行
除非eof循环
main =
do hSetBuffering stdin LineBuffering
loop
From http:// lambda .haskell.org / platform / doc / current / ghc-doc / libraries / haskell2010-1.1.1.0 / System-IO.html#g:11 :
< blockquote>
注意:hIsEOF可能会阻塞,因为它必须尝试从流中读取数据,以确定是否有更多数据要读取。
$ b $ < isEOF
,但 isEOF
防止th e程序在有更多字符可用之前转到 putStrLn
,或者实际上按下了 ^ D
。
所以你不应该使用 hIsEOF
/ isEOF
如果有的话,你准备阅读更多的字符的程序。
Here is minimal complete example:
import Control.Monad
import System.IO
loop :: IO ()
loop =
do line <- getLine
putStrLn line
eof <- isEOF
unless eof loop
main = loop
This program is supposed to read a line, print it out, stop if there is 'end of file' character in stdin
. It doesn't leave the loop at all.
If I put eof <- isEOF
before putStrLn line
the program behaves very strange (try it!). I cannot get it at all: how putStrLn
can possibly affect input stream and why doesn't the program terminate when I put 'end of file' character into stream (with Ctrl+D)?
Description of program's behavior when eof <- isEOF
goes before putStrLn line
:
After entering of a line, program does not print the entered line, but expects more input. As it gets more input, it starts to print previously entered lines. This is log of a test:
foo
boo
output: foo
bar
output: boo
baz
output: bar
< here I press Ctrl-D >
output: baz
Source:
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
NOTE: hIsEOF may block, because it has to attempt to read from the stream to determine whether there is any more data to be read.
The putStrLn
doesn't affect the isEOF
, but the isEOF
prevents the program from getting to the putStrLn
before more characters are available, or you have actually pressed ^D
.
So you should never use hIsEOF
/isEOF
until the point in the program where you are ready to read more characters if there are any.
这篇关于为什么EOF不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!