Si tiene el código log_out(), vuelva a escribirlo. Lo más probable es que puedas hacer:
static FILE *logfp = ...;
void log_out(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(logfp, fmt, args);
va_end(args);
}
Si se necesita información de registro adicional, se puede imprimir antes o después del mensaje que se muestra. Esto ahorra asignación de memoria y tamaños de búfer dudosos y así sucesivamente. Probablemente necesite inicializar logfpa cero (puntero nulo) y verificar si es nulo y abrir el archivo de registro según corresponda, pero el código existente log_out()debería lidiar con eso de todos modos.
La ventaja de esta solución es que simplemente puede llamarla como si fuera una variante de printf(); de hecho, es una variante menor de printf().
Si no tiene el código log_out(), considere si puede reemplazarlo con una variante como la descrita anteriormente. Si puede usar el mismo nombre dependerá de su marco de aplicación y de la fuente última de la log_out()función actual . Si está en el mismo archivo de objeto que otra función indispensable, tendrá que usar un nuevo nombre. Si no puede averiguar cómo replicarlo exactamente, tendrá que usar alguna variante como las que se dan en otras respuestas que asignen una cantidad adecuada de memoria.
void log_out_wrapper(const char *fmt, ...)
{
va_list args;
size_t len;
char *space;
va_start(args, fmt);
len = vsnprintf(0, 0, fmt, args);
va_end(args);
if ((space = malloc(len + 1)) != 0)
{
va_start(args, fmt);
vsnprintf(space, len+1, fmt, args);
va_end(args);
log_out(space);
free(space);
}
/* else - what to do if memory allocation fails? */
}
Obviamente, ahora llama al en log_out_wrapper()lugar de log_out(), pero la asignación de memoria y así sucesivamente se realiza una vez. Me reservo el derecho de sobreasignar espacio por un byte innecesario; no he verificado dos veces si la longitud devuelta por vsnprintf()incluye el nulo de terminación o no.