Якщо у вас є код 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()включаючи закінчуючий нуль, чи ні.