我想设计一个函数,它带有可变数量的参数,其中一个参数本身就是va_list
;但我的代码中出现错误,我不明白是什么...把一个va_list变量放在一个变量参数列表(!)里面
警告 - 我的问题不是关于设计一个代码做我想做的事情(我找到了一种方法来绕过这个问题),但只有理解我做错了什么......
解释我的问题,让我们先从一个简单的例子,即:一个功能ffprintf
这就像fprintf
,但是写的内容下载到若干字符串,字符串,其数量为由ffprintf
的第一个参数指示,其身份由下一个参数给出(这些参数的数量可能因呼叫而异,因此您必须使用变量argum ent list)。这样的功能会被这样使用:
FILE *stream0, *stream1, *stream2;
int a, b;
ffprintf (3, stream0, stream1, stream2, "%d divided by %d worths %f", a, b, (double)a/b);
而且它的代码是:
void ffprintf (int z, ...)
{va_list vlist, auxvlist;
FILE **streams = malloc (z * sizeof(FILE *));
va_start (vlist, z);
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *); // Getting the next stream argument
}
char const *format = va_arg (vlist, char const *); // Getting the format argument
for (int i = 0; i < z; ++i)
{va_copy (auxvlist, vlist); // You have to work on a copy "auxvlist" of "vlist", for otherwise "vlist" would be altered by the next line
vfprintf (streams[i], format, auxvlist);
va_end (auxvlist);
}
va_end (vlist);
free (streams);
}
这工作正常。现在,也有标准功能vfprintf
,它的原型是vfprintf (FILE *stream, char const* format, va_list vlist);
,并且你使用这样来创建具有可变参数列表中的其他功能:
void fprintf_variant (FILE *stream, char const* format, ...)
{
va_list vlist;
va_start (vlist, format);
vfprintf (stream, format, vlist);
va_end (vlist);
}
这太正常工作。现在,我的目标是这两个观念结合起来,创造一个功能,我会打电话vffprintf
,你会使用这样的:
FILE *stream0, *stream1, *stream2;
void fprintf_onto_streams012 (char const *format, ...)
{va_list vlist;
va_start (vlist, format);
vffprintf (3, stream0, stream1, stream2, format, vlist);
va_end (vlist);
}
我设计了下面的代码:
void vffprintf (int z, ...)
{va_list vlist, auxvlist, auxauxvlist;
va_start (vlist, z);
FILE **streams = malloc (z * sizeof(FILE *));
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *);
}
char const *format = va_arg (vlist, char const *);
va_copy (auxvlist, va_arg (vlist, va_list)); // Here I get the next argument of "vlist", knowing that this argument is of "va_list" type
for (int i = 0; i < z; ++i)
{va_copy (auxauxvlist, auxvlist);
vfprintf (streams[i], format, auxvlist);
va_end (auxauxvlist);
}
va_end (auxvlist);
va_end (vlist);
free (streams);
}
此代码编译顺利,但它不能正常工作...例如,如果我写了下面的完整代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void vffprintf (int z, ...)
{va_list vlist, auxvlist, auxauxvlist;
FILE **streams = malloc (z * sizeof(FILE *));
va_start (vlist, z);
for (int i = 0; i < z; ++i)
{streams[i] = va_arg (vlist, FILE *);
}
char const *format = va_arg (vlist, char const *);
va_copy (auxvlist, va_arg (vlist, va_list));
for (int i = 0; i < z; ++i)
{va_copy (auxauxvlist, auxvlist);
vfprintf (streams[i], format, auxauxvlist);
va_end (auxauxvlist);
}
va_end (auxvlist);
va_end (vlist);
free (streams);
}
void printf_variant (char const *format, ...)
{va_list vlist;
va_start (vlist, format);
vffprintf (1, stdout, format, vlist);
va_end (vlist);
}
int main (void)
{printf_variant ("Ramanujan's number is %d.\n", 1729);
return 0;
}
,我收到了段错误...为什么?!
P.-S .:对不起,这个很长的问题;但我希望它非常清楚,因为它是相当技术性的...
P.-S.2:我故意为这个问题使用了两个标签“va-list”和“variableargumentlists”,因为这对我感兴趣是va_list
,看作是类型,在(其他)变量参数列表中,被看作列表 ...因此,这些实际上是两个不同的概念。
所以问题是为什么最后一个例子失败? – this
是的,这正是:-) –
如果您忽略内存泄漏,看起来很好。 – this