Неправильный порядок действий ввода-вывода с использованием putStr и getLine
Вопрос
У меня есть следующий код:
main = do
putStr "Test input : "
content <- getLine
putStrLn content
Когда я запускаю его (с runhaskell
) или скомпилируйте его (ghc 6.10.4), результат будет примерно таким:
asd
Test input : asd
Почему это Test input : asd
печатается после asd
?
В примере кода на http://learnyouahaskell.com/, который использует putStr
, тот getLine
представленный результат отличается от моего.Когда я использую putStrLn
программа работает как ожидалось (печать, затем запрос и печать).
Это ошибка в ghc
, или это так, как это должно работать?
Решение
Это связано с тем, что ghci отключает буферизацию, в то время как программа, скомпилированная с помощью ghc, по умолчанию имеет буферизацию строк.Вы можете убедиться в этом, запустив это:
import System.IO
main = print =<< hGetBuffering stdout
В ghci вы видите NoBuffering
в то время как с runghc вы получаете LineBuffering
.Поскольку символ новой строки не печатается до тех пор, пока после пользовательский ввод, подсказка тоже этого не делает.
Исправьте это, добавив hFlush stdout
после вашего запроса (или отключите буферизацию с помощью hSetBuffering stdout NoBuffering
, но это, наверное, плохо).