制限時間内のキー入力検査
Posted feedbacks - OCaml
エスケープ文字を処理する関数を作れば文字列編集もできます。
leditを使っているとターミナル設定が無効化されるので、
インタプリタで実行する場合は外してください。
leditを使っているとターミナル設定が無効化されるので、
インタプリタで実行する場合は外してください。
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 45 46 47 48 | (*ocamlc unix.cma xxx.ml*)
open Unix;;
let tctrans descr status f1 f2 x =
let default = Unix.tcgetattr descr in
Unix.tcsetattr descr status (f1 default);
let res = f2 x in
Unix.tcsetattr descr status default;
res;;
let timeout v sec itimer f =
let t = ref v in
let itimer_init () =
ignore (setitimer itimer {it_interval=sec; it_value=sec});
t := v in
let itimer_bak =
setitimer itimer {it_interval=0.; it_value=0.} in
let signal_bak =
Sys.signal Sys.sigalrm (Sys.Signal_handle (fun _ -> t := not v)) in
let res = f itimer_init t in
let _ = setitimer itimer itimer_bak in
let _ = Sys.signal Sys.sigalrm signal_bak in
res;;
let input_checker sec s =
tctrans Unix.stdout Unix.TCSADRAIN
(fun t -> {t with Unix.c_echo = false; Unix.c_icanon = false})
(fun () ->
timeout false sec Unix.ITIMER_REAL (fun init_itimer timeout ->
let result = Buffer.create (String.length s) in
Printf.printf "Input(%s) => %s<ENTER>\n" s s;
for i = 1 to 3 do
Printf.printf " %d. result %!" i;
let c = input_char Pervasives.stdin in
let rec loop = function
| '\n' ->
let str = Buffer.contents result in
Printf.printf "\b\b\b\b\b\b\b%s => %s\n%!" str
(if !timeout then "TIME OUT" else
if str = s then "OK" else "NG");
Buffer.clear result;
| c ->
Buffer.add_char result c;
loop (input_char Pervasives.stdin)
in loop (init_itimer (); c)
done
)) ();;
(* input_checker 5. "ABCDE";; *)
|


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 ]