C 可变长度参数列表错误
许多年前,我编写了一个自定义打印函数,声明如下:C 可变长度参数列表错误,c,variadic-functions,C,Variadic Functions,许多年前,我编写了一个自定义打印函数,声明如下: void my_printf(char *format_string, ... ) { // too complex to list here } my_printf("Number of apples = %d\n",apple); my_printf_extra(debug_level,"Number of apples = %d\n",apple); void my_printf_extra(int extra,char *f
void my_printf(char *format_string, ... )
{
// too complex to list here
}
my_printf("Number of apples = %d\n",apple);
my_printf_extra(debug_level,"Number of apples = %d\n",apple);
void my_printf_extra(int extra,char *format_string, ... )
{
if (extra == some_test)
{
my_printf(** not quite sure what goes here **);
}
}
我可以这样称呼它:
void my_printf(char *format_string, ... )
{
// too complex to list here
}
my_printf("Number of apples = %d\n",apple);
my_printf_extra(debug_level,"Number of apples = %d\n",apple);
void my_printf_extra(int extra,char *format_string, ... )
{
if (extra == some_test)
{
my_printf(** not quite sure what goes here **);
}
}
这个功能一直工作得很好。现在,我希望创建一个包装函数,该函数在开始时接受一个额外的整数,如下所示:
void my_printf(char *format_string, ... )
{
// too complex to list here
}
my_printf("Number of apples = %d\n",apple);
my_printf_extra(debug_level,"Number of apples = %d\n",apple);
void my_printf_extra(int extra,char *format_string, ... )
{
if (extra == some_test)
{
my_printf(** not quite sure what goes here **);
}
}
void my_printf_extra(int extra,char*format_string,…
)
可以这样称呼:
void my_printf(char *format_string, ... )
{
// too complex to list here
}
my_printf("Number of apples = %d\n",apple);
my_printf_extra(debug_level,"Number of apples = %d\n",apple);
void my_printf_extra(int extra,char *format_string, ... )
{
if (extra == some_test)
{
my_printf(** not quite sure what goes here **);
}
}
我希望包装器函数以如下方式调用原始函数:
void my_printf(char *format_string, ... )
{
// too complex to list here
}
my_printf("Number of apples = %d\n",apple);
my_printf_extra(debug_level,"Number of apples = %d\n",apple);
void my_printf_extra(int extra,char *format_string, ... )
{
if (extra == some_test)
{
my_printf(** not quite sure what goes here **);
}
}
我猜是这样的:
void my_printf_extra(int extra,char *format_string, ... )
{
va_list vptr;
if (extra == some_test)
{
va_start(vptr,format_string);
my_printf(format_string,vptr);
va_end(vptr);
}
}
但它不起作用。在我的最终输出中,我看到
Number of apples = -46467968
或者一些这样的垃圾号(当真值为1时)。当用字符串调用我的\u printf\u extra时,我看到类似的垃圾。我怀疑我对va_列表的处理是错误的,但我不知道具体是如何处理的
编辑:my_printf()非常灵活,可以打印到各种不同的地方。有时它只是将文本附加到富编辑控件窗口。这完全取决于各种各样的标志以及正在打印的内容。由于
my\u printf
不需要va\u列表,因此您不能将其传递给它
在这种情况下,使用宏是有意义的:
#define my_printf_extra(extra, format_string, ... ) \
do {\
if ((extra) == some_test)\
{\
my_printf((format_string), __VA_ARGS__);\
}\
} while (0)
\u VA\u ARGS\u
宏将替换所有额外参数。请注意,这需要一个支持C99的编译器
或者,您可以修改my_printf以添加额外逻辑,将名称更改为内部名称,然后将my_printf
和my_printf_extra
定义为调用内部函数的宏:
void my_printf_impl(int extra, char *format_string, ... )
{
if (extra != some_test) {
return;
}
...
}
#define EXTRA_DEFAULT 0
#define my_printf(format_string, ...) \
my_printf_impl(EXTRA_DEFAULT, format_string, __VA_ARGS__)
#define my_printf_extra(extra, format_string, ...) \
my_printf_impl(extra, format_string, __VA_ARGS__)
将va_列表
传递给另一个函数不会像传递参数一样填充参数。这里一个合理的解决方案可能是使现有的my\u printf
成为一个更简单的例程,初始化va\u列表
,并将其传递给my\u printf\u core
,该例程完成其余工作。然后您的my\u printf\u extra
可以调用my\u printf\u core
而不是my\u printf
。(my_printf_core
可能等同于标记的原件中提到的vfprinf
,因此基本上是相同的解决方案,除非您需要在my_printf_core
中进行自定义)@Jean-Francois Fabre:我看不出复制品有什么帮助。代码和我的原版车一模一样。你误读了。1) 它不完全相同,因为它使用的是vfprintf
,2)它可以工作。因此,在一般情况下没有真正的解决方案,但是使用printf
系列函数,您可以使用vfprintf
计算出它,我不会打印到stdout。my_printf函数实际上相当复杂,可以打印到各种不同的位置或一个文件,或以各种颜色等图形方式打印,有时可以打印到多个位置。取决于标志您是否打印到文件?缓冲区?与c89兼容吗?@Jean-Françoisfare,我不这么认为<代码>\uuu VA\u ARGS\uuu
是在C99中引入的。