I have a C program that logs the duration of a process (substituted with sleep for illustrative purposes):
// Compilation: gcc time.c -lm -Wall -o time
// Execution: ./time
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <unistd.h>
int main (void) {
time_t begin = time(NULL);
sleep(4);
time_t end = time(NULL);
char buffer_hours[3];
int hours = floor((end-begin) / 3600);
sprintf(buffer_hours, "%d", hours);
if (hours < 10) strcat(buffer_hours, "0");
char buffer_minutes[3];
int minutes = round(hours / 60);
sprintf(buffer_minutes, "%d", minutes);
if (minutes < 10) strcat(buffer_minutes, "0");
printf("Time elapsed: %ld seconds (%s:%s hh:mm).\n\a", (end - begin), buffer_hours, buffer_minutes);
return 0;
}
The purpose is to show time in seconds as well as hours and minutes, but with a zero prefixed for when either is less than 10. This seems like an inefficient way of doing it, as 4 new variables are introduced as well as 4 lines of string handling. Can someone suggest a refactored way of how this could be done?
Hi @technossomy,
you can use printf's format capacity, see man 3 printf. Here is a simple version that also prints the other time intervals:
#include <stdio.h> // printf()
#include <stdlib.h> // atoi()
#include <time.h> // time()
#include <unistd.h> // sleep()
int main(int argc, char **argv) {
time_t beg = time(NULL);
sleep(atoi(argv[1]));
time_t end = time(NULL);
int secs = end - beg;
printf("Time elapsed: %d seconds (%d-%02d:%02d:%02d d-hh:mm:ss).\n", \
secs, secs/86400, secs/3600%24, secs/60%60, secs%60);
return 0;
}
For testing different time intervals, comment out the sleep call and replace int secs ... by int secs = atoi(argv[1]);. Start the prog via ./time seconds.
see the below .... , with or without minute/hour variables, no intermediate strings, and minimum 2 digit precision on number of ... seconds/minutes/hours.
you can pass a sleep delay on the command line ... if none supplied it'll waste 5 seconds of your valuable time 
#include <stdlib.h>
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <unistd.h>
int main (int argc, char **argv )
{
int secs=5;
secs = (argc == 2) ? atoi(argv[1]) : 5;
time_t begin = time(NULL);
printf(" sleeping for %d seconds \n", secs );
sleep(secs);
time_t end = time(NULL);
printf( " without any additional variables \n" );
printf("Time elapsed: %.2ld seconds (%.2ld:%.2ld hh:mm).\n\a", (end - begin), (long)floor((end-begin) / 3600), (long)( floor((end-begin) / 3600) / 60 ) );
int hours = floor((end-begin) / 3600);
int minutes = round(hours / 60);
printf( "\nwith minute and hour variables \n" );
printf("Time elapsed: %.2ld seconds (%.2d:%.2d hh:mm).\n\a", (end - begin), hours, minutes);
return 0;
}
use of "%.2ld" or "%.2d" - guarantees at least 2 digits
@technossomy,
fyi -
you can do away with the sleep (and save yourself some time
... just add the #seconds passed in to the end variable.
time_t end = time(NULL) + atoi(argv[1]);