我试过这个:
main = do hSetBuffering stdin NoBuffering c <- getChar
但是等到input被按下,这不是我想要的。 我想在用户按下后立即读取字符。
我在Windows 7上使用ghc v6.12.1。
编辑:我的解决方法是从GHC移动到WinHugs,正确支持这一点。
可能是一个错误:
http://hackage.haskell.org/trac/ghc/ticket/2189
以下程序重复输入的字符,直到按下退出键。
import IO import Monad import Char main :: IO () main = do hSetBuffering stdin NoBuffering inputLoop inputLoop :: IO () inputLoop = do i <- getContents mapM_ putChar $ takeWhile ((/= 27) . ord) i
由于hSetBuffering stdin NoBuffering行,不需要在击键之间按下Enter键。 此程序在WinHugs(sep 2006版本)中正常工作。 但是,直到按下回车键,GHC 6.8.2才会重复字符。 所有GHC可执行文件(ghci,ghc,runghc,runhaskell)都使用Windows XP Professional上的cmd.exe和command.com来重现问题…
是的,这是一个错误。 这是一个解决方法,以保存人们点击和滚动:
{-# LANGUAGE ForeignFunctionInterface #-} import Data.Char import Foreign.C.Types getHiddenChar = fmap (chr.fromEnum) c_getch foreign import ccall unsafe "conio.h getch" c_getch :: IO CInt
所以你可以用getChar
调用来代替getChar
的调用。
请注意,这是一个解决方法,仅适用于Windows上的ghc / ghci。 例如,winhugs没有bug,这个代码在winhugs中不起作用。
嗯..其实我看不到这个功能是一个错误。 当你阅读stdin
,这意味着你想用一个“文件”,当你打开缓冲你说没有需要读取缓冲区。 但这并不意味着模拟“文件”的应用程序不应该使用写入缓冲区。 对于Linux,如果你的终端处于“icanon”模式,它将不会发送任何输入,直到发生一些特殊事件(如Enter按或Ctrl + D)。 Windows中的控制台可能有一些类似的模式。
Haskeline包为我工作。
如果你需要单个字符,那么稍微改变一下这个例子。
getInputLine
变成getInputChar
"quit"
变成'q'
++ input
变成++ [input]
main = runInputT defaultSettings loop where loop :: InputT IO () loop = do minput <- getInputChar "% " case minput of Nothing -> return () Just 'q' -> return () Just input -> do outputStrLn $ "Input was: " ++ [input] loop