Of course, it's not hard to produce a "close enough to work" estimate for this particular type of example: %d takes up a max of 12 characters, %s takes up as much as the string is long, and then the format string's length.
You could write a parser that takes the arguments, like this:
Code:
int sprintfalloc(const char *fmt, ...)
{
va_list argp;
const char *s = fmt;
char *str;
size_t size = 0;
va_start(argp, fmt);
while(*s)
{
if (*s == '%')
{
switch(s[1])
{
case 's':
size += strlen((va_arg(argp, char *));
break;
case 'd':
size += 12; // We could calculate the size of course.
(void) va_arg(argp, int);
break;
case 'c':
size++;
break;
default:
// Do something here, perhaps?
}
}
}
va_start(argp, fmt);
str = malloc(size + 1);
vsprintf(str, fmt, argp);
va_end(argp);
}
Of course, it would get a whole lot more complicated if you needed to cope with more exotic variants of formatting, e.g "%10d" or "%10.19f", or worse yet "%*d". It can be dealt with, but at that point, it may make more sense to use a really large buffer, sprintf() to that buffer, and then copy to a smaller buffer if you need to keep the string around.
--
Mats