我想实现一个可变参数函数,其功能类似于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上查看failing。
注意:
printf()
或vprintf()
。 sprintf()
作为前缀,然后使用sprintf()
作为原始参数;但这也不是我的意思。完全不可能在纯C中将[[prepend自变量移植到va_list
中。完全可以确定,但是对于每个体系结构和compiler 和电话会议。
"%d "
放在带有编译时字符串分类的格式字符串前面,并轻松地在参数中添加数字。但是为此,格式必须是字符串文字。或者,如果您确实需要使用函数,那么我不会受到限制,即不对后面跟着这些的前缀分别使用printf
-
输出将是行缓冲的或全缓冲的,因此不会可能有任何区别。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <time.h>
#define wrapped_printf_macro(f_, ...) \
printf("%lld " f_, (long long)time(0), __VA_ARGS__)
int wrapped_printf(const char* format_str, ...)
{
static const char* const prefix = "%d ";
static const size_t prefix_length = 3;
va_list ap;
printf("%lld ", (long long int)time(0));
va_start(ap, format_str);
vprintf(format_str, ap);
va_end(ap);
}
int main()
{
wrapped_printf_macro("Hello world %d\n", 5678);
wrapped_printf("Hello world %d\n", 5678);
return EXIT_SUCCESS;
}
#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上查看failing。