4

目标是将 Haskell 中的 Nim 游戏编码为学校作业。我是 Haskell 的新手,当我尝试读取输入时会出现奇怪的行为。

目标是读取两个整数。而不是打印第一条消息,然后提示然后继续第二条消息,它只打印两条消息,我无法提供正确的输入。这里有什么问题?

type Board = [Int]      -- The board
type Heap  = Int        -- id of heap
type Turn  = (Int, Int) -- heap and number of stars to remove

readInt :: String -> IO Int
readInt msg = do putStr (msg ++ "> ")
                 inp <- getChar
                 let x = ord inp
                 return x

readTurn :: Board -> IO(Turn)
readTurn b = do heap <- readInt "Select heap:"
                amt <- readInt "Select stars:"
                print heap
                print amt
                return(heap, amt)
4

2 回答 2

7

问题是stdout默认情况下是行缓冲的,这意味着在您打印换行符之前没有任何输出。有两种方法可以解决这个问题:

  1. 在打印提示后使用hFlush stdout以刷新缓冲区。
  2. 在程序开始时使用hSetBuffering stdout NoBuffering以禁用输出缓冲。

此外,使用getCharandord将读取单个字符并为您提供其 ASCII 值,这可能不是您想要的。要读取和解析数字,请使用readLn

import System.IO (hFlush, stdout)

readInt :: String -> IO Int
readInt msg = do
    putStr (msg ++ "> ")
    hFlush stdout
    readLn
于 2012-04-12T13:28:19.370 回答
1

readChar一次只读取一个字符。我假设您想要阅读整行,将其转换为数字(可能不止一位),然后继续。您需要使用getLine :: IO Stringread :: Read a => String -> a

readInt :: String -> IO Int
readInt msg = do
    putStr (msg ++ "> ")
    hFlush stdout
    inp <- getLine
    return (read inp)
于 2012-04-12T13:27:06.537 回答