Если у вас есть код для log_out()
, перепишите его. Скорее всего, вы можете сделать:
static FILE *logfp = ...;
void log_out(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(logfp, fmt, args);
va_end(args);
}
Если требуется дополнительная информация для регистрации, которую можно распечатать до или после показанного сообщения. Это сохраняет распределение памяти и сомнительные размеры буфера и так далее и тому подобное. Возможно, вам нужно инициализировать logfp
в ноль (нулевой указатель) и проверить, является ли он нулевым, и открыть файл журнала соответствующим образом - но код в существующем log_out()
должен все равно иметь с этим дело.
Преимущество этого решения в том, что вы можете просто назвать его, как если бы это был вариант printf()
; действительно, это второстепенный вариант printf()
.
Если у вас нет кода log_out()
, подумайте, можете ли вы заменить его на вариант, такой как описанный выше. Возможность использования одного и того же имени будет зависеть от структуры вашего приложения и конечного источника текущей функции log_out()
. Если он находится в том же объектном файле, что и другая незаменимая функция, вам придется использовать новое имя. Если вы не можете понять, как точно его воспроизвести, вам придется использовать какой-то вариант, подобный приведенному в других ответах, который выделяет соответствующий объем памяти.
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? */
}
Очевидно, что теперь вы вызываете log_out_wrapper()
вместо log_out()
- но выделение памяти и т. Д. Выполняется один раз. Я оставляю за собой право перераспределять пространство одним ненужным байтом - я не перепроверил, содержит ли длина, возвращаемая vsnprintf()
, завершающий ноль или нет.