我有一个简单的程序,它只需从用户那里获取一个字符串和一个密钥,然后使用凯撒密码函数加密该字符串。函数本身能够正常工作,因此我不会展示其源代码。问题在于,当编译器编译程序时,它允许我输入所有的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的某些内容?它们只在函数的结果下执行吗?
此外,我创建的“prompt”函数不是问题所在,因为我已经用它们的相应putStr和getLine替换了所有的prompt使用,并且它仍然表现出相同的问题。
prompt str = do { putStr str; hFlush stdout; getLine }
。意思是:输入一个字符串并返回用户的输入。 - Will Nessstdout
是按行缓冲的。除非你填满整行,否则需要将其刷新。可使用do putStr "..." ; hFlush stdout ; getLine
。 - chihSetBuffering stdout NoBuffering
(来自System.IO
)。 - Thomas M. DuBuisson