I have found that the n parameter of snprintf() seems to be ignored in my code.

char asdf[10];
Serial1.println(snprintf(asdf, 2, "hello"));

This prints 5 when I would expect it to print 2. What is happening?

  • Does the variable asdf contain "hello" or "h"? If it contains "h" then the parameter has not been ignored. – Nick Gammon Oct 20 at 21:03
up vote 7 down vote accepted

snprintf() will not write more than <size> (snprintf's 2d argument) characters to your buffer, but it does count (and discard the extra) characters it would have written, had there been space enough, and that is the number it returns. Yeah, it can be confusing!

See this snprintf() reference.

  • 5
    It would be helpful because you could snprintf to a very small buffer, note the number returned, then malloc a buffer of the appropriate size, and do it again. That way you know how many bytes to allocate. – Nick Gammon Oct 20 at 21:01
  • 4
    @NickGammon: Or you can snprintf to no buffer whatsoever (a null destination pointer is explicitly described as a valid argument for the destlength==0 case) when measuring the length. – supercat Oct 20 at 21:52
  • 1
    Indeed. That is also done in Windows text output routines to measure how much space some text in some font would occupy, without actually drawing it. – Nick Gammon Oct 20 at 23:18

A test sketch for the Arduino Uno:

char buffer[10];

void setup() {
  Serial.begin(9600);
  int n = snprintf(buffer, 2, "hello");
  Serial.println(n);
  Serial.println(buffer);
}

void loop() {
}

As @JRobert wrote, the "would have" is the key. As far as I know only the snprintf and the vsnprintf return a "would have" number.

I think the reason is to be able to tell if the string was truncated. Suppose the 'size' parameter is 25 and the format string is very long, then the return value can be tested against 25. If the return value was 26 (the "would have" number of bytes), then the string was truncated.
This information was not possible to retrieve when the "would have" number was not available.

For completion, the man page for fprintf states:

The snprintf() function shall be equivalent to sprintf(), with the addition of the n argument which states the size of the buffer referred to by s. If n is zero, nothing shall be written and s may be a null pointer. Otherwise, output bytes beyond the n‐1st shall be discarded instead of being written to the array, and a null byte is written at the end of the bytes actually written into the array.

and, more relevant:

Upon successful completion, the snprintf() function shall return the number of bytes that would be written to s had n been sufficiently large excluding the terminating null byte.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.