While working on SSJ, I wrote the following function:
char*
strnewf(const char* fmt, ...)
{
va_list ap, apc;
char* buffer;
int buf_size;
va_start(ap, fmt);
va_copy(apc, ap);
buf_size = vsnprintf(NULL, 0, fmt, apc) + 1;
va_end(apc);
buffer = malloc(buf_size);
va_copy(apc, ap);
vsnprintf(buffer, buf_size, fmt, apc);
va_end(apc);
va_end(ap);
return buffer;
}
Usage:
char* string = strnewf("%s ate %d pigs", "maggie", 812);
/* do stuff with string... */
free(string);
It's quite useful when you need a formatted string on-the-fly but don't want to have to guess at the correct buffer size and risk a buffer overflow.
Isn't this already what `asprintf` does?
Huh, I never heard of asprintf before! It looks like it's GNU-only though, it's not even a POSIX function (like strdup is).
BSD has an implementation, too, and I think there is a musl one as well.
I tend to take non-standard things like that and strcasecmp and the like from the BSD libc. Each file corresponds to one function or one small family of functions, and doesn't require many (if any) other files to work.
strcasecmp was at least easy to get in MSVC:
#define strcasecmp stricmp
Same goes for strtok_r vs. strtok_s and a few other POSIX functions, they usually have reasonable drop-in replacements in the MS CRT. asprintf is an exception though, MSVC has no equivalent to that as far as I'm aware.
Nice to see I reinvented the wheel without even intending to. :P