Haskell: считайте вводимый символ из консоли сразу, не после новой строки

Я попробовал это:

main = do
    hSetBuffering stdin NoBuffering 
    c <- getChar

но это ожидает, пока Enter не нажат, который не является тем, что я хочу. Я хочу считать символ сразу после того, как пользователь нажмет его.

Я использую ghc v6.12.1 в Windows 7.

Править: обходное решение для меня перемещалось от GHC до WinHugs, который поддерживает это правильно.

26
задан Don Stewart 24 April 2011 в 16:23
поделиться

2 ответа

Возможно, это ошибка:

http://hackage.haskell.org/trac/ghc/ticket/2189

Следующая программа повторяет введенные символы до тех пор, пока не будет нажата клавиша escape.

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 не должно быть необходимости нажимать клавишу ввода между нажатиями клавиш. Эта программа корректно работает в WinHugs (версия sep 2006). Однако в GHC 6.8.2 символы не повторяются до тех пор, пока не будет нажата клавиша Enter. Проблема была воспроизведена со всеми исполняемыми файлами GHC (ghci, ghc, runghc, runhaskell), используя cmd.exe и command.com на Windows XP Professional...

20
ответ дан 28 November 2019 в 07:10
поделиться

Хм .. На самом деле я не считаю, что эта функция является ошибкой. Когда вы читаете stdin , это означает, что вы хотите работать с «файлом», а когда вы включаете буферизацию, вы говорите, что нет необходимости в буфере чтения. Но это не означает, что приложение, которое имитирует этот «файл», не должно использовать буфер записи. Для linux, если ваш терминал находится в режиме «icanon», он не отправляет никаких входных данных, пока не произойдет какое-то особое событие (например, нажатие Enter или Ctrl + D). Наверное, в консоли в Windows есть какие-то похожие режимы.

4
ответ дан 28 November 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: