【发布时间】:2019-07-11 16:51:27
【问题描述】:
我有一个简单的程序,它只从用户那里获取一个字符串和一个密钥,并使用凯撒密码函数对该字符串进行加密。该功能本身有效,因此我不会为此提供来源。问题是,当编译器编译程序时,它将允许我输入所有 getLines,然后在输入所有内容后,程序将打印所有 putStr 和 putStrLn 然后关闭。这只发生在程序使用“runhaskell”执行或作为exe编译和执行时,即。不在口译员中。这是程序:
main = do
choice <- prompt "Would you like to encrypt (1) or decrypt (2)? "
if choice == "1" then do
encrypt <- prompt "Enter code for encryption: "
k <- prompt "Enter key for the code: "
let key = read k in
putStrLn ("Encrypted message: " ++ (caesar key encrypt) ++ "\n")
else do
decrypt <- prompt "Enter code for decryption: "
k <- prompt "Enter key for the code: "
let key = read k in
putStrLn ("Decrypted message: " ++ (caesar (-key) decrypt) ++ "\n")
getLine
prompt str = do
putStr str
getLine
在解释器中运行时的输出:
Prelude Main> main
Would you like to encrypt (1) or decrypt (2)? 1 <- the one is user input
Enter code for encryption: Hello world <- user input
Enter key for the code: 2 <- user input
Encrypted message: Jgnnq"yqtnf <- program output
编译后执行时的输出:
1 <- user has to input before the console is printed out
Hello world <--┘
2 <--┘
Would you like to encrypt (1) or decrypt (2)? Enter code for encryption: Enter key for the code: Encrypted message: Jgnnq"yqtnf
关于 putStrLn 和 putStr 有什么我忽略的吗?它们是否仅作为函数或其他东西的结果执行?
另外,我创建的“提示”函数不是问题,因为我用它们各自的 putStr 和 getLine 替换了提示的所有用法,它仍然做了同样的事情。
【问题讨论】:
-
试试
prompt str = do { putStr str; hFlush stdout; getLine }。 -
stdout默认情况下是行缓冲的。除非你填满整条线,否则你需要冲洗它。使用do putStr "..." ; hFlush stdout ; getLine。 -
或者使用
hSetBuffering stdout NoBuffering(来自System.IO)。