3

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?

akshayk07
  • 2,092
  • 1
  • 20
  • 32
Kallel Omar
  • 1,208
  • 2
  • 17
  • 51
  • 4
    prefixhours is 0, you can't print that as %c. Internally the string gets terminated. – rustyx Aug 26 '17 at 11:19
  • @RustyX so what do you propose as solution? – Kallel Omar Aug 26 '17 at 11:22
  • @RustyX no I think that you didn't understand well what I want by prefixseconds=0 I mean by it no characters because it's in the case seconds>=10 so there's no need to add 0 before seconds number – Kallel Omar Aug 26 '17 at 11:30
  • The code you show is quiet repetitive. This is against the [DRY principal](https://en.wikipedia.org/wiki/Don%27t_repeat_yourself). – alk Aug 26 '17 at 11:41

1 Answers1

2

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.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    ooh I wasn't careful to that. yes you have right. 0 is finally '\0' char that means the end of string. Thank you @gsamaras. – Kallel Omar Aug 26 '17 at 11:38