使用 putStr 和 getLine 的错误 IO 操作顺序 [英] Wrong IO actions order using putStr and getLine

查看:15
本文介绍了使用 putStr 和 getLine 的错误 IO 操作顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

main = do
    putStr "Test input : "
    content <- getLine
    putStrLn content

当我运行它(使用 runhaskell)或编译它(ghc 6.10.4)时,结果是这样的:

When I run it (with runhaskell) or compile it (ghc 6.10.4) the result is like this:

asd
Test input : asd

为什么 Test input : asd 打印在 asd 之后?

Why is Test input : asd being printed after asd?

http://learnyouahaskell.com/ 上的代码示例中,它使用了 putStrgetLine 显示的输出与我的不同.当我使用 putStrLn 时,程序按预期工作(打印,然后提示,然后打印).

In the code sample on http://learnyouahaskell.com/, which uses putStr, the getLine's presented output is different than mine. When I use putStrLn the program works as expected (print, then prompt, and print).

这是 ghc 中的一个错误,还是它应该工作的方式?

Is it a bug in ghc, or it is the way that it should work?

推荐答案

这是因为 ghci 禁用了缓冲,而使用 ghc 编译的程序默认具有行缓冲.你可以通过运行这个来看到这一点:

This is because ghci disables buffering, while a program compiled with ghc has line buffering by default. You can see this by running this:

import System.IO
main = print =<< hGetBuffering stdout

在 ghci 中,您会看到 NoBuffering 而在 runghc 中,您会看到 LineBuffering.由于在用户输入之后之前不会打印换行符,因此提示也不会.

In ghci you see NoBuffering while with runghc you get LineBuffering. Since the newline character doesn't print until after the user input, the prompt doesn't either.

通过在提示后添加 hFlush stdout 来修复它(或使用 hSetBuffering stdout NoBuffering 禁用缓冲,但这可能很糟糕).

Fix it by adding hFlush stdout after your prompt (or disable buffering with hSetBuffering stdout NoBuffering, but that’s probably bad).

这篇关于使用 putStr 和 getLine 的错误 IO 操作顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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