Tick-Tock Goes the Clock, Part II

From last week’s Lesson, the code I wrote for my clock program outputs the current hour and minute. I also want it to update, to keep running and output the next minute and so on. To me, that’s the difference between a clock program and code that just outputs the current time.

An updating clock program requires some sort of loop. In the following code, I add a loop to the program:

#include <stdio.h>
#include <time.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
              );
    }

    return(0);
}

The code is identical, save for the addition of the endless while loop. Rather than display the time in discrete minute values, the output is a continuous stream of text:

It is now 12:25
It is now 12:25
It is now 12:25
It is now 12:25
It is now 12:25
...

Eventually, the time changes. This program qualifies as a clock, but it’s not what I had in mind. Instead, I want to see output like this:

It is now 12:25
It is now 12:26
It is now 12:27
...

The output above ticks every minute, updating the clock program’s output with the system time. To make this possible, a second loop is required. I would encourage you to try to concoct the second loop on your own. That’s because it’s not the easiest thing to do, though once you see the answer it makes sense.

Yes! Go off and figure out the second loop, the one that delays output for a minute. Do it on your own!

I’ll wait.

[ ♪ musical interlude ♫ ]

Did you do it? Probably not. Anyway.

Consider that the time_t value represents seconds ticked. So to make output pause for one minute, I add 60 to the time_t value stored in the now variable and then wait for the output of the time() function to be greater than or equal to that value. Here is the test:

while( now+60 > time(NULL) )
    ;

In the while loop’s test, 60 seconds are added to the value of now. The time(NULL) expression returns the current clock tick value. So the loop waits 60 seconds; when time(NULL) returns a value 60 seconds in the future, the loop stops. At that point, the next clock value is output:

It is now 12:32
It is now 12:33
It is now 12:34
It is now 12:35
It is now 12:36
^C

Click here to view the complete code.

With a little output modification, I have my clock program. I just noticed one problem: The clock’s time wasn’t in sync with the system time. I checked the seconds elapsed, and discovered that the code counts the next minute based on when the program starts, not when the system clock hits :00 seconds. The surprising thing is that only one change is required to fix this problem — and it might even be something you came up with, if you worked on your own solution to determining how to implement the second loop.

See next week’s Lesson for the solution.

Leave a Reply