Question:
A problem with C++ How a timer works?
Reza
2018-01-22 11:36:21 UTC
Hi everyobe. I have want to code a simple program in cpp.
This is how it works;
User has 60 seconds to answer unlimited questiones and just after a minute program stops and gives result.
But how to make it sensitive on time?
Here is a part of code:

int n = 0 , res;
clock_t start = clock() , end;
do{
puts (question [n]);
cin >> answer;
check_ans ();
res = check_time();
n++;
}while (res)

Which check_ans function checks answer and check_time checkes spent time and returns 0 if spent time is lees than 60 seconds.
So how to run check_time continuously during program?
Seven answers:
Marvin
2018-01-23 23:05:50 UTC
Under what platform?



If you are using Visual C++ with MFC then I can thing of a dozen ways. If you are using Qt then there are a dozen ways. If you are using GNU without Qt it is a bit more complex.
?
2018-01-22 22:14:59 UTC
You can use signals: https://linux.die.net/man/2/signal

Specifically sigalarm, using the alarm function: https://linux.die.net/man/2/alarm



Of course, using signals can be complicated.



Another way would be to spawn a child process, or thread, which asks the questions and gets the answers. Then have the parent process/thread run the timer, and after 60 seconds have the parent kill the child and process the answers.
bocephusmcguire
2018-01-22 15:54:17 UTC
This is the beauty of low-level languages like C/C++ -- you can go around the standard library and communicate directly with the hardware. While running your timer loop, you poll the keyboard and construct the user's response one character at a time. Forget about cin, that will never work.
husoski
2018-01-22 15:15:06 UTC
That is indeed a problem for C++, which doesn't have any sort of built-in event system. Your program does not have control during the execution of a cin>> operation, so you can't be testing or showing the time remaining while the user is thinking of a response.



Also, the clock() function is defined to return processing time (often called "CPU time") and on many implementations that will not include time spent waiting for input. See:

http://www.cplusplus.com/reference/ctime/clock/



You probably want to use time(), even though it's only got a 1 second resolution, but there may be a higher-resolution timer defined in the C++11 header.

http://www.cplusplus.com/reference/chrono/



The time() function is good enough for 60s elapsed time, and you can start exactly on the start of a second with something like:



time_t start, temp;

temp = time();

do { start = time(); } while (start == temp);



Each time you want to test for 60 sec. (or more) elapsed time, use something like:



if ( (time() - start) >= 60) { .... time has expired ...} /* or */

while ( (time() - start) < 60) { ... repeat while time remains .... }



That will NOT interrupt anything. Your program doesn't run while blocked, waiting for a response from the console. About the best you can do is display the seconds remaining (60 - (time() - start)) just before the input request.



If you decide to use clock() anyway, replace time_t with clock_t and use 60*CLOCKS_PER_SEC as your sixty second value; and (clock() - start)/CLOCKS_PER_SEC as your estimated number of seconds remaining.



- - - - -



If you want to use implementation-dependent functions, lot's of people have used kbhit/getch/getche functions on Windows to re-invent gets() without blocking for input. Most Linux/Unix systems have curses or ncurses, with the same functionality and more. There's a pdcurses implementation floating around that's almost compatible with curses, so you might be able to use that to make a program that will compile and run on PC or Mac (MacOS is BSD Unix under the hood since the OSX.)



The threading approach suggested by Chris is interesting, but hard to keep control of since C++ doesn't have a way to terminate a thread that isn't needed any more. There's a way to kill all threads, but that's open to resource leaks and is really only reasonable as an emergency measure when aborting the program.
2018-01-22 15:03:55 UTC
It's many years since I last used C++, but doesn't "cin" halt program execution until a key is pressed? During this time the timer will not be updated, check the IO libraries documentation for a function that doesn't wait for a keypress and modify your loop appropriately.
Robert J
2018-01-22 12:36:15 UTC
Add a non-blocking keyboard check function.



That allows you to see if a character is available and skip past the input routine if the user has not pressed any key.



If they have pressed a key, add it to the input string (plus a null in the next location to show the new end), unless it's enter - in that case, go to your check_ans() function and then clear the input string ready for the next answer.



This gives an example of how to create a non-blocking routine:

http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/comment-page-1/



( "kbhit" was a function included in some early versions of C but omitted from later standards).
?
2018-01-22 11:54:40 UTC
Here's the basic idea (threading): https://stackoverflow.com/a/28947000/5734311


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...