31

I've tried this:

main = do
    hSetBuffering stdin NoBuffering 
    c <- getChar

but it waits until the enter is pressed, which is not what I want. I want to read the character immediately after user presses it.

I am using ghc v6.12.1 on Windows 7.

EDIT: workaround for me was moving from GHC to WinHugs, which supports this correctly.

4

5 回答 5

22

是的,这是一个错误。这是一个解决方法来节省人们点击和滚动:

{-# 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对 的呼叫getHiddenChar

请注意,这仅适用于 Windows 上的 ghc/ghci。例如,winhugs 没有该错误,并且此代码在 winhugs 中不起作用。

于 2012-11-13T22:52:19.803 回答
20

可能是一个错误:

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 标准输入 NoBuffering 行,因此不必在击键之间按回车键。该程序在 WinHugs(2006 年 9 月版)中正常运行。但是,GHC 6.8.2 在按下回车键之前不会重复字符。在 Windows XP Professional 上使用 cmd.exe 和 command.com 使用所有 GHC 可执行文件(ghci、ghc、runghc、runhaskell)重现了该问题...

于 2010-06-06T11:21:42.570 回答
4

嗯..实际上我看不出这个功能是一个错误。当您阅读时stdin,这意味着您要使用“文件”,而当您关闭缓冲时,您会说不需要读取缓冲区。但这并不意味着模拟该“文件”的应用程序不应该使用写缓冲区。对于 linux,如果您的终端处于“icanon”模式,它不会发送任何输入,直到发生某些特殊事件(如按下 Enter 或 Ctrl+D)。Windows中的控制台可能有一些类似的模式。

于 2010-06-06T11:46:54.273 回答
3

Haskeline包对我有用。

如果您需要单个字符,则只需稍微更改示例即可。

  1. getInputLine变成getInputChar
  2. "quit"变成'q'
  3. ++ 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
于 2013-09-25T02:11:04.043 回答
0

来自@Richard Cook 的评论

使用hidden-char:提供跨平台的 getHiddenChar 功能

于 2022-01-11T04:02:04.910 回答