制限時間内のキー入力検査
Posted feedbacks - Haskell
標準ではない System.Timeout モジュールを使う
see: System.Timeout.hs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | module Main (main) where
import System.Environment
import System.IO
import System.Timeout
main :: IO ()
main = do { prog <- getProgName
; args <- getArgs
; case args of
t:str:_ -> loop 3 (inputChecker (read t) str)
_ -> usage prog
}
loop :: Int -> IO () -> IO ()
loop 0 _ = return ()
loop n f = f >> loop (n-1) f
usage :: String -> IO ()
usage prog = hPutStrLn stderr $ prog ++ " <timeout> <string>"
inputChecker :: Int -> String -> IO ()
inputChecker t s
= do { hPutStr stderr $ "input(" ++ s ++ ") => "
; hSetBuffering stdin NoBuffering
; c <- hGetChar stdin
; ms <- timeout (t*1000000) (hGetLine stdin)
; case ms of
Nothing -> hPutStrLn stdout "\n result => TIME OUT" >> hFlush stdout
Just s' -> if s == (c:s') then hPutStrLn stdout " result => OK" >> hFlush stdout
else hPutStrLn stdout " result => NG" >> hFlush stdout
}
{-
*Main> :main 5 ABCDEF
input(ABCDEF) => ABCDEF
result => OK
input(ABCDEF) => A
result => TIME OUT
input(ABCDEF) => PQR
result => NG
*Main> _
-}
|
ああーっ。仕様6を満たしてなかった。 timeout というので短絡的に仕様6が頭から 飛んじゃったみたい。 仕様6があるほうがやさしいかも。。。 というわけで変更。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | import System.Environment
import System.IO
import System.Time
main :: IO ()
main = do { prog <- getProgName
; args <- getArgs
; case args of
t:str:_ -> loop 3 (inputChecker (read t) str)
_ -> usage prog
}
loop :: Int -> IO () -> IO ()
loop 0 _ = return ()
loop n f = f >> loop (n-1) f
usage :: String -> IO ()
usage prog = hPutStrLn stderr $ prog ++ " <timeout> <string>"
inputChecker :: Int -> String -> IO ()
inputChecker t s
= do { hPutStr stderr $ "input(" ++ s ++ ") => "
; hSetBuffering stdin NoBuffering
; c <- hGetChar stdin
; start <- getClockTime
; s' <- hGetLine stdin
; end <- getClockTime
; let interval = diffClockTimes end start
; if interval > noTimeDiff {tdSec = t}
then hPutStrLn stdout " result => TIME OUT" >> hFlush stdout
else if s == (c:s')
then hPutStrLn stdout " result => OK" >> hFlush stdout
else hPutStrLn stdout " result => NG" >> hFlush stdout
}
{-
*Main> :main 5 ABCDEF
input(ABCDEF) => ABCDEF
result => OK
input(ABCDEF) => ABC
result => NG
input(ABCDEF) => ABCDEF
result => TIME OUT
-}
|




raynstard
#3420()
Rating0/2=0.00
関数 InputCheckerは、以下の仕様を満たしてください。
たとえば、「InputCheker(5, "ABCDEF")」と指定した場合、 出力例はこんな感じです。
1. input(ABCDEF) =>と出力して入力待ちをし、ユーザーが「ABCDEF<ENTER>」を入力したとき、 入力開始から5秒以内ならば「OK」、5秒をこえていれば「TIME OUT」を出力します。 このとき、ユーザーがキーを押下しなければ1. を出力してから たとえ10秒たっていても「TIME OUT」にはならないので注意してください。 時間計測はあくまでユーザーが入力を開始してからです。
このお題はraynstardさんの投稿です。ご協力ありがとうございます。
[ reply ]