challenge 制限時間内のキー入力検査

ユーザーの入力を検査する関数 InputCheckerを作成して 3回連続実行してください。

関数 InputCheckerは、以下の仕様を満たしてください。

  1. 引数に 時間(秒) Nと文字列 Sを受け取ること。
  2. ユーザからの標準入力とあらかじめ指定された S を比較し、 一致すれば「OK」、一致しなければ「NG」を標準出力へ出力すること。
  3. ユーザーの入力がN秒以内に完了しなかった場合は、比較せず 「TIME OUT」を標準出力へ出力すること。
  4. 経過時間はユーザーが入力を開始した地点から計測すること。
  5. ENTER キーの入力によってユーザー入力が完了したと仮定すること。
  6. ユーザの入力が完了するまでは、完了を待ち続けること

たとえば、「InputCheker(5, "ABCDEF")」と指定した場合、 出力例はこんな感じです。

  1. input(ABCDEF) =>ABCDEF<ENTER>
    1. result => OK
    2. result => NG
    3. result => TIME OUT

1. input(ABCDEF) =>

と出力して入力待ちをし、ユーザーが「ABCDEF<ENTER>」を入力したとき、 入力開始から5秒以内ならば「OK」、5秒をこえていれば「TIME OUT」を出力します。 このとき、ユーザーがキーを押下しなければ1. を出力してから たとえ10秒たっていても「TIME OUT」にはならないので注意してください。 時間計測はあくまでユーザーが入力を開始してからです。


このお題はraynstardさんの投稿です。ご協力ありがとうございます。

Posted feedbacks - C++

Windows専用。
  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
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
#include <windows.h>
#include <stdexcept>
#include <string>

char GetChar(HANDLE h)
{
    char c;

    DWORD read;

    while (true)
    {
        if (! ::ReadFile(h, &c, 1, &read, NULL))
        {
            throw std::runtime_error("::ReadFile() failed");
        }

        if (read == 1 && c != '\r') // skip CR
        {
            break;
        }
    }

    return c;
}

void WriteString(HANDLE h, const std::string& s)
{
    const char* p = s.c_str();

    DWORD size = s.size();

    while (size)
    {
        DWORD written;

        if (! ::WriteFile(h, p, size, &written, NULL))
        {
            throw std::runtime_error("::WriteFile() failed");
        }

        p += written;

        size -= written;
    }

    ::FlushFileBuffers(h);
}

void InputChecker(DWORD timeout, const std::string& expected)
{
    HANDLE hStdIn = ::GetStdHandle(STD_INPUT_HANDLE);

    HANDLE hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);

    if (hStdIn == INVALID_HANDLE_VALUE || hStdOut == INVALID_HANDLE_VALUE)
    {
        throw std::runtime_error("cannot get console handle");
    }

    WriteString(hStdOut, "input(" + expected + ") => ");

    ::WaitForSingleObject(hStdIn, INFINITE);

    const DWORD beg = ::GetTickCount();

    std::string s;

    char c;

    while ((c = GetChar(hStdIn)) != '\n')
    {
        s.append(1, c);
    }

    const DWORD end = ::GetTickCount();

    std::string result;

    if (end - beg >= timeout * 1000)
    {
        result = "TIME OUT";
    }
    else if (s == expected)
    {
        result = "OK";
    }
    else
    {
        result = "NG";
    }

    WriteString(hStdOut, "   result => " + result + "\r\n");
}

int main()
{
    try
    {
        while (true)
        {
            InputChecker(5, "ABCDEF");
        }
    }
    catch (std::exception& e)
    {
        WriteString(::GetStdHandle(STD_ERROR_HANDLE), std::string("error: ") + e.what() + "\r\n");
    }
}

Index

Feed

Other

Link

Pathtraq

loading...