How to get character from keyboard within a period of time

Hi guys. I'm having a problem with my project. I'm writing a quiz game that player must type the answer in the console windows within 10 seconds. So how can i use the cin>>, scanf(), or are any other way to get character from the keyboard within 10s, and after that, the program will fill the default answer and continue to the next step without waiting forever?

ps: Sorry because my English is not good!
Hmm, there are several answers to this, but the simplest is to only timeout if the user does not press any keys:
See http://cplusplus.com/forum/general/64802/#msg350595

The timeout is in milliseconds, so ten seconds is 10000. You might want to do a loop to give some countdown feedback.

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
#include <iomanip>
#include <iostream>
#include <string>
using namespace std;

// iskeypressed()           - is a key press waiting to be read right now?
// iskeypressed( 1000 )     - wait up to a second for a key press before timeout
//                            (specify max wait timeout in milliseconds)
// iskeypressed( INFINITE ) - wait for a key press with no timeout (i.e. forever)

#ifdef _WIN32

#define NOMINMAX
#include <windows.h>

bool iskeypressed( unsigned timeout_ms = 0 )
  {
  return WaitForSingleObject(
    GetStdHandle( STD_INPUT_HANDLE ),
    timeout_ms
    ) == WAIT_OBJECT_0;
  }

#else

#include <unistd.h>
#include <poll.h>

#define INFINITE (-1)

bool iskeypressed( unsigned timeout_ms = 0 )
  {
  struct pollfd pls[ 1 ];
  pls[ 0 ].fd     = STDIN_FILENO;
  pls[ 0 ].events = POLLIN | POLLPRI;
  return poll( pls, 1, timeout_ms ) > 0;
  }

#endif

bool countdown( unsigned seconds )
  {
  for (unsigned n = 0; n < seconds; n++)
    {
    cout << "\r" << setw( 2 ) << (seconds - n) << "> " << flush;
    if (iskeypressed( 1000 )) return true;
    }
  cout << "\r" << setw( 2 ) << 0 << "> " << flush;
  return false;
  }

int main()
  {
  cout << "What is my favorite color?\n";
  string answer = "orange";
  if (countdown( 10 )) getline( cin, answer );
  else                 cout << answer << "\n";

  if (answer == "green")
    cout << "Good job, my favorite color is green!\n";
  else
    cout << "Alas, you guessed wrong.\n";

  return 0;
  }

Notice that the user can still cause the game to wait forever by beginning to answer, but not pressing ENTER.

If you must have a more advanced timeout than that, let me know.
cout << "\r" produces artifacts in the input.
Every second it sends me to the beginning, overwriting what I previously inputted.
Notice that the user can still cause the game to wait forever by beginning to answer, but not pressing ENTER.
Didn't observe that
I am exceedingly curious as to why my post was reported, and why, exactly?

Did I not directly answer the OP's exact question?
Did I abuse him?
Did I suggest incorrect or bad code?
Did I not explain the limitations of the code and offer to provide a more advanced example if this did not suffice?
Did I abuse the forum policies in any way?

@ne555
If you run the program exactly as I listed it above, the instant you press a key, the function terminates and returns you to main -- leaving nothing to be overwritten. If you are getting odd artifacts in your output, your terminal is one of: broken, improperly configured, or too old/dumb to understand one of the oldest, most universally-understood control codes in existence.

The purpose of "\r" is to return the cursor to the beginning of the line, so that the countdown is updated.
poll() is returning 0 till I press Enter.

Edit: http://www.cplusplus.com/forum/general/5304/#msg23940 needed to configure termios
Last edited on
Ah, yes, that makes sense.
i tried that and it just waits for ever, doesn't do anything after 10 seconds, until i hit enter
Hmm... what OS/CC/and TERM?
windows vista or 7, whats cc and term?

anywho no idea what is waitforsingleobject but i did get this to work:
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
#include <iostream>
#include <string>
#include <windows.h>
#include <iomanip>
using namespace std;

bool hasanykeybeenpressed()
{
    for (int i = 0; i < 255; ++i)
        if (GetAsyncKeyState(i))
            return true;
    return false;
}

bool my_timer(int seconds)
{
    int start_t = time(0);
    start_t %= 1000;
    int end = start_t + seconds; ++end;
    int previous = start_t;
    for(;;)
        {
            int local = time(0);
            local %= 1000;
            if (local > previous)
                {
                    previous = local;
                    int stp = time(0); stp %= 1000;
                    int check = end -stp;
                    if (check < 0)
                        return false;
                    cout << "\r" << setw(2) << (check) << "> " << flush;
                    if (hasanykeybeenpressed())
                        return true;
                }
        }
    return false;
}

int main()
{
    cout << "What is my favorite color?\n";
    string answer = "orange";
    bool pass = false;
    if (my_timer(10))
        {
            getline( cin, answer );
        }
    else pass = false;
    if (answer == "green")
        pass = true;
    if (pass == true)
        cout << "\nGood job, my favorite color is green!\n";
    else
        cout << "\nAlas, you guessed wrong.\n";
    cout << "Goodbye.\n" << flush << endl;
    return 0;
}


although I have to be careful because other programs can cause the status of getasynckeystate to change.
Topic archived. No new replies allowed.