getLine 不会停止

getLine doesn't stop

我的程序是这样的

main :: IO String
main = do
  putStrLn "input a"
  a <- getChar
  putStrLn "input b"
  b <- getLine
  putStrLn "input c"
  c <- getChar
  return a:c:b

行为:我打印了 "input a",程序等待我输入一个字符并按 return。从那里,它滚动过去 getLine,但从未让我输入任何内容。我怎样才能让它按照我的意图去做?

P.S.: 这段代码可能有更多问题,但让我们专注于我现在的问题。

我想我知道你在说什么(即使你的代码没有编译),这应该可以解决它(至少它 usual.y 对我来说):

import System.IO

hSetBuffering stdin NoBuffering
hSetBuffering stdout NoBuffering

顺便说一句:我认为我在 eshell 和 GHCi 中的 windows 中有这些问题,但我不是 100% 确定 - bash 中从未有过虽然


当然也可能是 getChargetLine 的奇怪组合 ;)

无论如何:

import System.IO

main :: IO ()
main = do

  hSetBuffering stdin NoBuffering
  hSetBuffering stdout NoBuffering

  putStrLn "input a"
  a <- getLine
  putStrLn "input b"
  b <- getLine
  putStrLn "input c"
  c <- getLine
  print (a,b,c)

应该打印提示让你输入 3 个输入,最后打印元组

问题是由默认启用的 stdin 缓冲 引起的。

  1. 在文件的顶层导入 IO

    import System.IO
    
  2. 添加到您的 main(在任何 getChar 调用之前)

    hSetBuffering stdin NoBuffering
    
import System.IO
main = do
  hSetBuffering stdin NoBuffering
  putStrLn "input a"
  a <- getChar
  putStrLn "input b"
  b <- getLine
  putStrLn "input c"
  c <- getChar
  print $ a:(c:b)

当您按 X 然后 Enter 时,您会 X\n 进入键盘缓冲区。

getCharX 但离开 \n。然后 getLine 只读 \n 并立即完成。

您可以使用另一个 getLine 读取尾随 \n 以在读取 b

之前清理键盘缓冲区
main :: IO String
main = do
  putStrLn "input a"
  a <- getChar
  getLine --clean kbd buffer
  putStrLn "input b"
  b <- getLine
  putStrLn "input c"
  c <- getChar
  return (a:c:b)