Reputation: 14869
I am writing a simple console application in LInux/C++ that accepts user input from command line. I am using std::getline( std::cin ) / std::cin >> text
in a thread.
After 10 seconds I would like to stop accepting console input and write a text message then do other things. I am using a separate thread for the timer.
This approach doesn't work since I cannot check that 10 seconds have elapsed until the user has not inserted any text.
Is there any better way to stop the application accepting text and go to another piece of line? I was thinking to use settimer
and signals programming but I would like something to call from a different thread for simplicity.
Regards
AFG
Upvotes: 3
Views: 1800
Reputation: 14869
It works nice but a small piece of code is needed that 'consumes' the byte.
Below the usage of your kbhit()
:
int main(int argc, const char** argv ){
while( !kbhit() ){
// do whatever you want here while
// entering the text
std::cout << "..while you write!" << std::endl;
} // stops when you hit 'ENTER'
std::string line;
std::getline( std::cin, line ); // consume/stores into line
// what was written until hitting 'ENTER'
}
Upvotes: 0
Reputation: 14461
A thread is overkill for this. In your input loop use select() to determine if stdin is ready for reading. You can check the time via a call to time() and exit the loop if 10 seconds have elapsed.
Upvotes: 2
Reputation:
You can use ncurses or if you don't want to, you can use select as described in this blog post. Basically, you can use select
and specify the timeout. If the stdin FD is set, then you can read from it safely and won't block. If you want more info on select, check this out and of course Wikipedia. It's a handy call to know about. For example,
// if != 0, then there is data to be read on stdin
int kbhit()
{
// timeout structure passed into select
struct timeval tv;
// fd_set passed into select
fd_set fds;
// Set up the timeout. here we can wait for 1 second
tv.tv_sec = 1;
tv.tv_usec = 0;
// Zero out the fd_set - make sure it's pristine
FD_ZERO(&fds);
// Set the FD that we want to read
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
// select takes the last file descriptor value + 1 in the fdset to check,
// the fdset for reads, writes, and errors. We are only passing in reads.
// the last parameter is the timeout. select will return if an FD is ready or
// the timeout has occurred
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
// return 0 if STDIN is not ready to be read.
return FD_ISSET(STDIN_FILENO, &fds);
}
See also this SO question on Peek stdin using pthreads
Upvotes: 6