我需要制作
vprintf
的包装,以便可以完成类似 printf 的函数的多个实现。这段代码演示了这个问题:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void print_fmt2(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
void print_fmt1(const char *fmt, ...)
{
va_list args, args_copy;
va_start(args, fmt);
va_copy(args_copy, args);
print_fmt2(fmt, args_copy);
va_end(args_copy);
va_end(args);
print_fmt2("\r\n");
}
int main ()
{
print_fmt1("test return %s %u\r\n", "is", 0);
return 0;
}
上面的代码,使用 gcc 11.4,Linux 编译,输出:
test return 3447949600
但我期望和想要实现的是:
test return is 0
问题应该是使用
va_copy
宏,但我不知道出了什么问题。
我必须遵守C99标准。
有什么想法吗?
谢谢。
你不能那样做。
这就是为什么标准可变参数函数总是有两种变体:一种可变参数函数,另一种采用
va_list
参数。
就像在您展示的示例中一样,有
vprintf
使用 va_list
参数。如果你想“级联”你的函数,你需要对它们做同样的事情。
所以你需要有例如
void print_fmt2(const char *fmt, va_list args)
{
vprintf(fmt, args);
}
void print_fmt1(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
print_fmt2(fmt, args);
va_end(args);
}
你不能这样做,但你可以使用宏来归档你想要的东西:
void print_fmt2(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
va_end(args);
}
#define print_fmt1(...) \
{ \
print_fmt2(__VA_ARGS__); \
print_fmt2("\r\n"); \
}
int main ()
{
print_fmt1("test return %s %u\r\n", "is", 0);
return 0;
}