I usually have a static buffer and I don't want to use a dynamic buffer.
char buf[BUFLEN];
I have to construct a long string, and it is quite easy to call snprintf multiple times:
int n = 0; n += snprintf(&buf[n], BUFLEN - n, ...); n += snprintf(&buf[n], BUFLEN - n, ...); n += snprintf(&buf[n], BUFLEN - n, ...); n += snprintf(&buf[n], BUFLEN - n, ...);
I was convinced the return value was the real number of characters written in buf, not counting final '\0'. In this case, the above code works.
I just noticed the return value of snprintf() is the number of characters of the generated string as if the buffer was long enough. So the above code doesn't work.
The return value of snprintf() is useful if you want to dynamically reallocate the buffer so it can store all the string. In my case I would prefer to truncate the string at the end of the static buffer. The above code should be redesigned as:
int n = 0; n += snprintf(&buf[n], BUFLEN - n, ...); if (n >= BUFLEN - n) return; n += snprintf(&buf[n], BUFLEN - n, ...); if (n >= BUFLEN - n) return; n += snprintf(&buf[n], BUFLEN - n, ...); if (n >= BUFLEN - n) return; n += snprintf(&buf[n], BUFLEN - n, ...); if (n >= BUFLEN - n) return;
The code starts being not readable. I'm thinking to create a new snprintf2():
int snprintf2(char *str, size_t size, const char *format, ...) { va_list args;
va_start(args, format); int n = vsnprintf(str, size, format, args); va_end(args); return (n >= size) ? (size - 1) : n; }