Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sprintf format issue

Hi,

I am doing a simple thing with string formatting:

sprintf(tmp_str,"%d.%d.%3d", version.major, version.minor, version.patch);

The version structure has values { 0, 5, 1 } and char tmp_str[20]. I want to achieve string like "0.5.001". Instead of getting this format, I am getting "0.5.d". 

For a curiosity I tried to change the format to "%3d.%d.%d" and I got "d.0.5". Format "%d.%d.%d" works as expected - 0.5.1.

I am using SDK 17.0.2 and SES 5.60.

Can somebody advise me how to brush sprintf to work as expected? I am not asking for workarounds how to get the expected string format rather to get sprintf working.

Thanx.

Best regards,

peter

Parents
  • Hi Torbjørn,

    I am based on ble_peripheral, ble_app_template.

    The version string I am cheking through DIS service. I now tried to use NRF_LOG_INFO this way (the structure values are 0, 5, 1):

    sprintf(tmp_str,"%d.%d%.3d", version.major, version.minor, version.patch);
    
    NRF_LOG_INFO("Firmware version: v%s", tmp_str);
    
    printf("Firmware version: v%s", tmp_str);
    

    I am getting output on the console:

    <info> app: Firmware version: v

    There is no version number in the output form NRF_LOG_INFO and nothing from the printf().

    Best regards,

    peter

  • Hi Peter

    What is the type of the version.major, version.minor and version.patch fields?

    Could you try to cast them to int in the call to sprintf?

    sprintf(tmp_str,"%d.%d%.3d", (int)version.major, (int)version.minor, (int)version.patch);

    If it's still not working, could you check the value of the tmp_str buffer in the debugger?

    Best regards
    Torbjørn

  • Hi Ted,

    thanx for your suggestion. We moved a bit, still not at the goal.

    I had the printf precision off so I changed it to yes. The result is as follows:

    - when using string format "%d.%d.%3d" the output is "v0.5.  1"

    - when using string format "%d.%d%.3d", the output is "v0.5001"

    A bit better but still not what we would like to see :)

    Best regards,

    peter

  • Hi Ted,

    I realized I need to use the following string format: "%d.%d.%03d". Then I am getting the output as expected: "0.5.001".

    Thanx a lot, Ted and Torbjørn, for an excellent support.

    Best regards,

    peter

  • Hi  Peter

    I assume "%d.%d.%.3d" would also work? 

    Anyway, excellent to hear that you were able to get it working Slight smile

    Best regards
    Torbjørn

  • Hi Torbjørn,

    "%d.%d%.3d" gives me "v0.5001".

    Thanx again to both of you for the support.

    Best regards,

    peter

  • Hi Tobjørn,

    I believe the leading zero in "%03d" is necessary to get output that has as many leading zeroes as needed to create fixed width tokens. But this should work with numeric and string tokens.  No reason "%03s" or "%010s" or similar would output differently in terms of width.

    Regarding this language detail, I came across this subtle C formatting syntax several years ago when I wanted fix column output.  In particular leading zeroes provided me text fields which would alphabetize at a Unix shell prompt.  I am reluctant to assume "%3d" will product desired output without testing on the same target hardware which Peter has.  Testing on my side shows that "%3d" does not pad output with leading zeroes on a typical Ubuntu host running a modified, libc6 based "hello world" program.

    And so too I would be assuming at this point that the leading zero in "%03d" can be any printable character, e.g. "%z3d" would pad with leading "z" characters but I must test this to be sure.  Somewhere too there is documentation among libc6 materials on this less often used feature of printf() family formatters.

    - Ted

Reply
  • Hi Tobjørn,

    I believe the leading zero in "%03d" is necessary to get output that has as many leading zeroes as needed to create fixed width tokens. But this should work with numeric and string tokens.  No reason "%03s" or "%010s" or similar would output differently in terms of width.

    Regarding this language detail, I came across this subtle C formatting syntax several years ago when I wanted fix column output.  In particular leading zeroes provided me text fields which would alphabetize at a Unix shell prompt.  I am reluctant to assume "%3d" will product desired output without testing on the same target hardware which Peter has.  Testing on my side shows that "%3d" does not pad output with leading zeroes on a typical Ubuntu host running a modified, libc6 based "hello world" program.

    And so too I would be assuming at this point that the leading zero in "%03d" can be any printable character, e.g. "%z3d" would pad with leading "z" characters but I must test this to be sure.  Somewhere too there is documentation among libc6 materials on this less often used feature of printf() family formatters.

    - Ted

Children
  • Hi Ted

    "%03d" won't work, but "%.3d" worked fine in my testing at least. 

    I have used similar syntax many times earlier in order to display 32-bit registers as padded hex values: 

    // Provide hexadecimal formatting. Example, 2 is displayed as 0x00000002
    "0x%.8x"

    Regardless, I wouldn't be surprised if this can vary a bit with the implementation of the standard libraries. 

    Best regards
    Torbjørn

Related