为什么EOF不起作用? [英] Why isEOF doesn't work?

查看:262
本文介绍了为什么EOF不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是最小的完整示例:

  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 $ < putStrLn 不会影响 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

解决方案

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

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆