My clock program is almost complete! It generates the current time as output and it updates the current time every minute. The only step remaining is to synchronize the program’s output with the system time. I want to ensure that when the system reads :00 seconds that the program ticks over to the next minute.
The modification to the code from last week’s Lesson is cinchy. It’s a change to Line 20 in the code, the second while loop that pauses until the next minute occurs:
while(time(NULL)%60)
;
The time(NULL)
expression returns the current clock tick value, the number of seconds elapsed since midnight January 1, 1970. The value ends in a multiple of 60 as one minute clicks to the next. So if you use the expression %60
(mod sixty), the while statement returns true only when the clock ticks to the next minute. This is exactly the condition I need to keep my clock program’s output in sync with the system clock.
Click here to view the entire code.
The program’s output, however, is less than desirable. The initial line is output fine, but once the top of the minute hits, the output streams for a second and makes me unhappy. That’s because the code runs so fast that the next minute holds while the clock tick value is still true for time(NULL)%60
.
To remove the streaming output for that one second, a delay must be added to the code. After the :00 minute occurs, the code must pause for over one second. To add the pause, I used the sleep() function, which is prototyped in the unistd.h
header file. I inserted the following line before the inner while loop:
sleep(2);
Here’s the full code:
#include <stdio.h> #include <time.h> #include <unistd.h> int main() { time_t now; struct tm *clock; while(1) { /* fetch the current time */ time(&now); /* fill the time structure */ clock = localtime(&now); /* display the clock */ printf("It is now %2d:%02d\n", clock->tm_hour, clock->tm_min ); /* delay */ sleep(2); /* wait until the next minute */ while(time(NULL)%60) ; } return(0); }
The problem with this solution is that not every compiler implements the sleep() function. If not, you can add a delay such as:
while( now+2 > time(NULL) )
;
The above loop easily replaces the sleep(2)
statement, adding a 2-second pause to the program and preventing the top-of-the-minute streaming ugliness.
With this final change, my clock program is complete: It displays the current time, updating at the top of the minute in coordination with the system clock.
OK, here’s a challenge: write a program that displays a proper analog clock face in a console. You’re the ncurses expert so it shouldn’t be too difficult…!
That’s actually where this was going, Chris. My first effort is a digital clock, which is where this series came from. The dial clock is the next step. Unfortunately, I’ve been diverted from this project to do other things, but I’ll return to it.
Thanks for the vote of confidence!