Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Displaying time string created using asprintf

I want display a string in this form: "in 3 days 00:15:07" or "in 00:15:07" in the case days is 0

so I wrote some code as follows

#include<stdio.h>

#define LEASE_TIME_USING_DAYS "in %d days %c%d:%c%d:%c%d\n"
#define LEASE_TIME_NOTUSING_DAYS "in %c%d:%c%d:%c%d\n"

int main(){
    int seconds, minutes, hours, days;
    char *leasetime;

    /* Just for test */
    seconds = 7;
    minutes = 15,
    hours = 0;
    days = 3;
    /*End just for test*/

    char prefixseconds, prefixminutes, prefixhours;
    if(seconds<10) prefixseconds=48; else prefixseconds=0;
    if(minutes<10) prefixminutes=48; else prefixminutes=0;
    if(hours<10) prefixhours=48; else prefixhours=0;
    if(days>0) asprintf(&leasetime,LEASE_TIME_USING_DAYS, days, prefixhours, hours, prefixminutes, minutes, prefixseconds, seconds);
    else asprintf(&leasetime,LEASE_TIME_NOTUSING_DAYS, prefixhours, hours, prefixminutes, minutes, prefixseconds, seconds);

    printf("lease time = %s\n", leasetime);
    printf(LEASE_TIME_USING_DAYS, days, prefixhours, hours, prefixminutes, minutes, prefixseconds, seconds);
}

I get this output in the console:

lease time = in 3 days 00:
in 3 days 00:15:07

I don't know exactly why the created string with asprintf (the first displaying message) is displayed in this way. I want it to be like the result of the second displayed message.

Does anyone have an idea where I went wrong?

like image 209
Kallel Omar Avatar asked Jun 05 '26 13:06

Kallel Omar


1 Answers

If you changed seconds and hours to be greater than 10, you would see that the problem persists.

When prefixhours is 0 you try to print it as a character (%c) but that's not going to happen, because 0 is treated like the null terminator of the string.

As a result, depending on what zeroes you inject into your string, the string gets terminated (before it prints out what you expect).


@RustyX's solution is to do this:

if(seconds<10) prefixseconds=48; else prefixseconds='0';
if(minutes<10) prefixminutes=48; else prefixminutes='0';
if(hours<10) prefixhours=48; else prefixhours='0';

instead of what you do now (so that the null terminator is not injected into the string). Notice that you should keep your data types as the ones in your question for your variables).


As @xing mentioned:

change this:

%c%d:%c%d:%c%d

to this:

%02d:%02d:%02d

and you will be fine, by doing this:

asprintf(&leasetime,LEASE_TIME_USING_DAYS, days, hours, minutes, seconds);

02 ensures that you will get the desired padding.

like image 137
gsamaras Avatar answered Jun 07 '26 09:06

gsamaras