Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits

...

A compliant solution avoids assuming that snprintf() succeeds regardless of its arguments and tests the return value of the function before using the buffer the function was passed to format output into. In addition, a compliant solution takes care to null-terminate the formatted string in case This solution also treats as an error the case where the provided buffer wasn't large enough for snprintf() to append the terminating null.

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <string.h>
 
extern void log_message(const char *);

void f(int i, int width, int prec) {
  char buf[40];
  int n;
  n = snprintf(buf, sizeof(buf), "i = %*.*i", width, prec, i);
  if (n < 0 || n >= sizeof(buf)) {
    /* Handle snprintf() error */
    strcpy(buf, "unknown error");
  }

  /* Null-terminate buffer in case of overflow */
  buf[sizeof(buf) - 1] = '\0';    
  log_message(buf);
}

When the length of the formatted string is unbounded, it is best to invoke the function twice, once with a NULL buffer to determine the size of output, then dynamically allocate a buffer of sufficient size, and finally call snprintf() again to format the output into the dynamically allocated buffer. Even with this approach, the success of all calls still needs to be tested, and any errors still must be appropriately handled. A possible optimization is to first attempt to format the string into a reasonably small buffer allocated on the stack and, only when the buffer turns out to be too small, allocate one of a sufficient size dynamically. This approach is shown in the following compliant solution.

...