4

目的は、学校の課題として Haskell で Nim のゲームをコーディングすることです。私は Haskell を初めて使用し、入力を読み取ろうとすると奇妙な動作をします。

目標は、2 つの整数を読み取ることです。最初のメッセージを出力してプロンプトを出してから 2 番目のメッセージに進む代わりに、2 つのメッセージを出力するだけで、適切な入力を行うことができません。ここで何が問題なのですか?

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

The problem is that stdout is line-buffered by default, which means that nothing gets output until you print a newline. There are two ways to solve this:

  1. Use hFlush stdout after printing the prompt to flush the buffer.
  2. Use hSetBuffering stdout NoBuffering at the start of your program to disable output buffering.

Also, using getChar and ord will read a single character and give you its ASCII value, which is probably not what you wanted. To read and parse a number, use 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一度に1文字だけ読み取ります。代わりに、1行全体を読み取り、それを数値(おそらく、1桁以上)に変換して続行したいとします。あなたは使用する必要がありgetLine :: IO Stringますread :: 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 に答える