Michael said:
What is the rationale for snprintf to "return the number of characters
(excluding the trailing '\0') which would have been written to the final
string if enough space had been available"?
It allows you to find out by how much to enlarge your final string
in order to fit it in. What is troubling me about this is that snprintf
takes a size_t parameter and returns an int, which is broken by design.
Returning 0 on error and the hypothetical number of written characters
including the string terminator with return type size_t would IMO have
been better.
This just twists my noodle in a knot every time! What is the proper way
to test the return value for overflow?
From the C99 standard:
"7.19.6.5 The snprintf function
Synopsis
1
#include <stdio.h> int snprintf(char * restrict s, size_t n,
const char * restrict format, ...);
Description
2 The snprintf function is equivalent to fprintf, except that the output
is written into an array (specified by argument s) rather than to a
stream. If n is zero, nothing is written, and s may be a null pointer.
Otherwise, output characters beyond the n-1st are discarded rather than
being written to the array, and a null character is written at the end
of the characters actually written into the array. If copying takes
place between objects that overlap, the behavior is undefined.
Returns
3 The snprintf function returns the number of characters that would have
been written had n been sufficiently large, not counting the terminating
null character, or a neg ative value if an encoding error occurred.
Thus, the null-terminated output has been completely written if and only
if the returned value is nonnegative and less than n.
"
So, I would use allocated buffers and do something along the lines
char *buf;
size_t buf_size;
int retval;
buf = NULL;
buf_size = 0;
while (1) {
retval = snprintf(buf, buf_size, "Test with buf of size %zu\n",
buf_size);
if (retval < 0) {
/* Treat encoding error or die */
}
else if (retval<buf_size) {
break; /* We finally made it */
}
else {
char *tmp;
if ( (tmp=realloc(buf, (size_t) retval + 1)) == NULL ) {
/* Give up trying to write this string or die */
}
buf = tmp;
buf_size = (size_t) retval + 1;
}
}
I did not test it but you see that it deals with the problem
that, depending on buf_size, the length of the output varies
so we need to adjust the size a second time.
What is the name and address of the person responsible for this?
I think this is slighty OT here. Try comp.std.c but I guess
they won't tell you either.
-Michael