传递va_list的一部分

时间:2014-05-06 21:04:18

标签: c++ variadic-functions

如何从第n个元素开始传递部分va_list或复制部分到另一个va_list?

int main (int x, char**argv) {
    va_list clientArgs;
    va_copy(clientArgs, argv[3]); // get all input parameters after 3rd cmd line arg

    foo(clientArgs);

    va_end(clientArgs);
    ....

或者使用va_copy方法......?

3 个答案:

答案 0 :(得分:1)

任何代码都不可移植,甚至不能保证工作(未定义的行为和所有这些)

但是,有可能,如下面的代码所示:

#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <stdarg.h>

void VarShowArgs(int n, va_list args)
{
    for(int i=0; i<n; ++i)
    {
        printf("Arg #%d: %d\n", i+1, va_arg(args, int));
    }
}

void ShowArgs_StartAtFourthParam(int n, ...)
{
    va_list args;
    int dummy;

    va_start(args,n);          // n is param #1 (value = 8)
    dummy = va_arg(args, int); // Remove Param #2 from args (value = 1)
    dummy = va_arg(args, int); // Remove Param #3 from args (value = 2)

    // Show arguments starting at Param #4 (which should be value = 3)
    VarShowArgs(n - 2, args);  // Minus 2 because we removed 2 params from the args.

    va_end(args);
}


int main(void)
{
    // First param says how many more args there will be.
    // This function shows the values starting at the 4th argument (value = 3)
    ShowArgs_StartAtFourthParam(8, 1, 2, 3, 4, 5, 6, 7, 8);
    getch();
    return 0;
}

<强>输出

Arg #1: 3
Arg #2: 4
Arg #3: 5
Arg #4: 6
Arg #5: 7
Arg #6: 8

答案 1 :(得分:0)

你是什么意思&#34; va_list的一部分&#34;?这个问题并没有多大意义。

va_list是一个迭代器对象,允许您一次迭代一个函数的参数 - va_start将其初始化为指向当前函数的特定参数后的参数,va_arg获取(复制)当前指向的参数并将其递增以指向下一个参数。

在任何情况下,va_list都不会封装参数列表 - 它只是一个类似于抽象指针的对象,它引用了参数列表。

您可以将指向va_list对象的指针传递给其他函数,并让该函数调用va_arg来处理某些参数。返回后,您可以调用va_arg来处理更多参数,但这并不是真正意义上的参数列表的副本。

您可以使用va_copy复制va_list,以便让两个迭代器通过参数列表。然后每个都是独立的,因此每个人都会看到va_copy完成之后的所有参数。

没有办法创建一个va_list对象,该对象引用除传递给当前函数的参数以外的任何内容...

答案 2 :(得分:0)

你不能直接这样做。 va_start的第二个参数应该是函数参数列表中省略号(...)之前的最后一个参数的名称。使用其他任何东西都会导致最不确定的行为。

为了能够近似您所追求的内容,您必须知道va_list前面的值是什么。您可以使用va_arg()阅读它们,然后将va_list左侧的内容传递给您的其他功能:

void function(int arg1, char *arg2, ...)
{
    va_list args;
    va_start(args, arg2);
    int i = va_arg(args, int);
    double d = va_arg(args, double);
    foo(args);
    va_end(args);
}

显然,如果变量列表中的参数都是相同的类型,则可以使用循环来迭代前N个这样的参数。请注意,无法找出提供了多少参数;您的代码必须“知道”。例如,printf()使用格式字符串来告诉它提供了多少个参数(以及每个参数的类型)。