Sleep() still allows input

What I'm trying to do is pause my program for 2.5 seconds so that there's enough time to read some text before you make an input. Sleep(2500) seemed to do this, but if you put an input in during those 2.5 seconds, it's still registered by the program and the input will be used immediately after the 2.5 seconds are up and I don't want this to happen. Can anyone recommend an alternative to Sleep() or something to use in conjunction with Sleep() to prevent this from happening?
Depending on how you read the input, you can clear the input buffer before reading the input, after the Sleep() is complete.
If during those 2.5 seconds, you don't want the input to appear at all, then you'll have to use OS-specific calls. For instance, on Windows, you could use the SetConsoleMode function:
http://msdn.microsoft.com/en-us/library/ms686033(v=VS.85).aspx

I haven't used this function before, but it looks like before the call to Sleep(), you'll have to disable the ENABLE_ECHO_INPUT flag. Then, after the call to Sleep() you must clear the input stream and re-enable the flag.
Last edited on
I'm reading the input by using cin >> move;. How would I go about clearing the input buffer after Sleep()?

EDIT:

move is double. Not sure if it matters, but I just wanted to clarify anyway.
Last edited on
1
2
3
Sleep(2500)
std::cin.sync();
std::cin >> move;


EDIT: Metroid Prime is awesome
Last edited on
Adding cin.sync(); doesn't seem to have made any difference.

EDIT:

I'm not sure if clearing is necessarily what I want to do. I'm thinking more of disabling keyboard input until the 2.5 seconds are up.
Last edited on
What about this?

1
2
3
4
5
6
#include <limits>

Sleep(2500);
std::cin.ignore ( std::numeric_limits< std::streamsize >::max() );
std::cin.sync();
std::cin >> move;
I got a few compilation errors:

warning C4003: not enough actual parameters for macro 'max'
error C2589: '(' : illegal token on right side of '::'
error C2143: syntax error : missing ')' before '::'
error C2059: syntax error : ')'

EDIT:

They're all on the cin.ignore line.
Last edited on
heh, that's a globally visible macro that shouldn't be there.

1
2
3
4
5
6
7
#include <limits>
#undef max //undefine the globally visible max macro

Sleep(2500);
std::cin.ignore ( std::numeric_limits< std::streamsize >::max(), '\n' );
std::cin.sync();
std::cin >> move;


Note that the above only disallows one input. If the user didn't hit the enter key during the Sleep() cycle, then they will have to press enter before entering the move. If they put in two inputs (like if they did: 4 [enter], 5 [enter] then cin would take in the 5 and put it into the move. This is starting to look more and more like a hack, so you will probably have to do something like I described above (using OS-specific calls) to disable user input before Sleep() and to re-enable it after.

shacktar wrote:
If during those 2.5 seconds, you don't want the input to appear at all, then you'll have to use OS-specific calls. For instance, on Windows, you could use the SetConsoleMode function:
http://msdn.microsoft.com/en-us/library/ms686033(v=VS.85).aspx

I haven't used this function before, but it looks like before the call to Sleep(), you'll have to disable the ENABLE_ECHO_INPUT flag. Then, after the call to Sleep() you must clear the input stream and re-enable the flag.


Like I said, I haven't used that function so there may be more to it than that. I don't think ENABLE_ECHO_INPUT disables the input from going into the read buffer, so you'll have to find an OS-specific way to block that.
Last edited on
closed account (DSLq5Di1)
@shacktar
What is the purpose of using ignore in your snippet?
The line with ignore can be used as a "press enter to continue", like at the end of a console application. This line has the added effect, in this case, of removing any of the user's input up to and including the first time they pressed enter while the sleep cycle was running. It's a hack in this case because, if the user hadn't entered anything during the sleep cycle, the user would have to press enter to continue before entering the move. And, if the user made several inputs, or just pressed the enter key multiple times, the ignore would remove the first newline but the next characters up to the next newline would go into cin >> move , which isn't what the OP wants.
This problem was bugging me, so I implemented a solution (Windows). Note that disabling user input is not what a "nice" console application should do :)

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
#include <iostream>
#include <windows.h> //for Windows-specific console stuff
#include <limits> //for numeric_limits

#undef max //disable the globally visible "max" macro

int main() 
{
     HANDLE hConsole = GetStdHandle( STD_INPUT_HANDLE );

     //Start off with some basic console I/O
     double move = 0;

     std::cout << "Please enter the move: ";
     std::cin >> move;
     std::cin.sync();

     std::cout << "Move entered: " << move << std::endl;
	
     //Now, start the sleep cycle to allow the program to do whatever
     //it has to do (and discard user input in the process)

     std::cout << "Starting to sleep" << std::endl;

     //Save the current console mode
     DWORD originalConsoleMode;
     GetConsoleMode( hConsole, &originalConsoleMode ); 

     //Now turn the ENABLE_ECHO_INPUT flag off
     //This makes it so any user input is not reflected on the screen
     DWORD mode = 0;
     SetConsoleMode( hConsole, mode & ~ENABLE_ECHO_INPUT ); 

     Sleep(5000);

     //Remove any input during the sleep cycle
     FlushConsoleInputBuffer( hConsole );

     //Restore original console mode
     SetConsoleMode( hConsole, originalConsoleMode );

     //Sleep cycle complete
     std::cout << "Sleeping has ended" << std::endl;

     //Read a move again (any input during the sleep cycle should not affect this)
     std::cout << "Please enter another move: ";
     std::cin >> move;
     std::cin.sync();

     std::cout << "Move entered: " << move << std::endl;

     std::cout << std::endl << "Press ENTER to continue" << std::endl;
     std::cin.ignore( std::numeric_limits< std::streamsize >::max(), '\n' );

     return 0;
}


EDIT: Re-implemented using FlushConsoleInputBuffer (starting a new thread was ugly and unnecessary anyway)
Last edited on
Good grief!

Input comes whether or not you like it, so the way to deal with it is to deal with it.

On Windows, you can simply tell it to go away:
http://www.google.com/search?btnI=1&q=msdn+FlushConsoleInputBuffer

Hence,

1
2
Sleep( N );
FlushConsoleInputBuffer( GetStdHandle( STD_INPUT_HANDLE ) );

If you are using *nix, let me know.
I can tell I'm out of my depth here, but couldn't one simply do a test like
1
2
3
time_t time = time(NULL);
while(3 > (time - time(NULL)))
     cin.ignore()


Though this will ignore the first input even if it is after the three seconds it's meant to wait.
That assumes that there is an input to ignore.
Topic archived. No new replies allowed.