Я хочу реализовать функцию variadic, которая ведет себя как printf, за исключением того, что она печатает некоторый префикс. Например, скажем, я хочу, чтобы префикс был значением time(0)
. если я позвоню:
wrapped_printf("Hello, world %d", 5678);
Я ожидаю что-то вроде:
1571441246 Hello, world 5678
в качестве вывода.
Очевидно, что замена строки формата не имеет большого значения;Это меня беспокоит вариадный бизнес. Должен ли я реализовать это как функцию, принимающую ...
? Принимая va_list
? И как мне добавить мои дополнительные аргументы?
Это то, что у меня есть сейчас. Он компилируется и запускается (это действительно C89 даже ...), но дополнительные аргументы запутаны.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
int wrapped_printf(const char* format_str, ...)
{
static const char* const prefix = "%d ";
static const size_t prefix_length = 3;
va_list ap;
size_t format_string_length = strlen(format_str);
char* const prefixed_format_str = malloc(format_string_length + prefix_length + 2);
/* 1 for the trailing '\0' and 1 for a line break */
if (prefixed_format_str == NULL) { exit(EXIT_FAILURE); }
strncpy(prefixed_format_str, prefix, prefix_length);
strncpy(prefixed_format_str + prefix_length, format_str, format_string_length);
prefixed_format_str[prefix_length + format_string_length] = '\n';
prefixed_format_str[prefix_length + format_string_length + 1] = '\0';
va_start(ap, format_str);
return printf(
prefixed_format_str,
(int) time(0),
ap);
va_end(ap);
}
int main()
{
wrapped_printf("Hello world %d\n", 5678);
return EXIT_SUCCESS;
}
Посмотрите не удалось в Coliru.
Примечания:
- Должен быть сделан только один звонок, но это может быть либо
printf()
, либо vprintf()
. - Можно использовать большой строковый буфер,
sprintf()
префикс в него, затем sprintf()
исходные аргументы впоследствии;но это также не то, что я имею в виду. - Я не возражаю против использования кода, специфичного для компилятора, - но если вы предлагаете это, попробуйте охватить более одного компилятора на более чем одной платформе - и особенно GCC илиclang в GNU / Linux с процессором AMD64.