Se você tiver o código log_out()
, reescreva-o. Provavelmente, você pode fazer:
static FILE *logfp = ...;
void log_out(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(logfp, fmt, args);
va_end(args);
}
Se houver necessidade de informações de registro extras, elas podem ser impressas antes ou depois da mensagem exibida. Isso economiza alocação de memória e tamanhos de buffer duvidosos e assim por diante. Você provavelmente precisa inicializarlogfp
para zero (ponteiro nulo) e verificar se ele é nulo e abrir o arquivo de log conforme apropriado - mas o código existente log_out()
deve lidar com isso de qualquer maneira.
A vantagem dessa solução é que você pode simplesmente chamá-la como se fosse uma variante de printf()
; na verdade, é uma variante menor emprintf()
.
Se você não tem o código log_out()
, considere se você pode substituí-lo por uma variante como a descrita acima. Se você pode usar o mesmo nome, dependerá de sua estrutura de aplicativo e da fonte final da log_out()
função atual . Se estiver no mesmo arquivo de objeto que outra função indispensável, você terá que usar um novo nome. Se você não conseguir descobrir como replicá-lo exatamente, terá que usar alguma variante, como as fornecidas em outras respostas, que aloca uma quantidade adequada de memória.
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, você agora chama o em log_out_wrapper()
vez de log_out()
- mas a alocação de memória e assim por diante é feita uma vez. Eu me reservo o direito de superalocar espaço em um byte desnecessário - não verifiquei duas vezes se o comprimento retornado por vsnprintf()
inclui o nulo de terminação ou não.