Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 可变长度参数列表错误_C_Variadic Functions - Fatal编程技术网

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中引入的。