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 Torbjørn,

    the variables are of int type.

    I checked the tmp_str values just after calling the sprintf(). You can see the values on the screenshot:

    Best regards,

    peter

  • Hi Peter

    Then I am running low on ideas, it works fine here ;)

    Are you able to zip your project folder (including project and source files) and share it with me, so I can test out your exact configuration?

    You might want to remove the build files first, to reduce the file size. 

    Best regards
    Torbjørn

  • Hello Peter and Torbjørn,

    Peter I realize a few days have passed since your initial post.  Have you been able to solve your printf() formatting issue yet?  Today while working on a different project and problem I came across a new project dialog in Nordic's version of Segger (Nordic SES release 5.6), with extra support for nRF Connect SDK projects.  A "Common Project Settings" dialog there catches my eye.  There are references to several printf functionalities, most of which are disabled by default.

    One of the options is called "printf width/precision".  Here is a window capture of this dialog box:SES "Choose Common Project Settings"

    When I initially wrote and suggested to try "%03d" format specifier in place of "%3d" specifier, I first wrote a short C program to be sure this specifier worked.  Running the program on the host workstation confirmed this.  The version of C which I was able to test against is:

    $ /lib/x86_64-linux-gnu/libc.so.6
    GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.2) stable release version 2.31.

    Compiling C natively under Ubuntu 20.04, libc6 printf libraries are fully enabled by default.  Printf family functions however, as you likely know, can be too large for microcontrollers with limited flash and other memory, so significant parts (or all) of printf formatting are often disabled by default in firmware development settings.

    Perhaps in your project environment some of these printf functionalities are disabled right now, like the ones in the window capture above?

    - Ted

Reply
  • Hello Peter and Torbjørn,

    Peter I realize a few days have passed since your initial post.  Have you been able to solve your printf() formatting issue yet?  Today while working on a different project and problem I came across a new project dialog in Nordic's version of Segger (Nordic SES release 5.6), with extra support for nRF Connect SDK projects.  A "Common Project Settings" dialog there catches my eye.  There are references to several printf functionalities, most of which are disabled by default.

    One of the options is called "printf width/precision".  Here is a window capture of this dialog box:SES "Choose Common Project Settings"

    When I initially wrote and suggested to try "%03d" format specifier in place of "%3d" specifier, I first wrote a short C program to be sure this specifier worked.  Running the program on the host workstation confirmed this.  The version of C which I was able to test against is:

    $ /lib/x86_64-linux-gnu/libc.so.6
    GNU C Library (Ubuntu GLIBC 2.31-0ubuntu9.2) stable release version 2.31.

    Compiling C natively under Ubuntu 20.04, libc6 printf libraries are fully enabled by default.  Printf family functions however, as you likely know, can be too large for microcontrollers with limited flash and other memory, so significant parts (or all) of printf formatting are often disabled by default in firmware development settings.

    Perhaps in your project environment some of these printf functionalities are disabled right now, like the ones in the window capture above?

    - Ted

Children
  • 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

Related