vsnprintf和varargs无法正常工作,结果很奇怪

时间:2014-11-10 00:29:34

标签: c variadic-functions

我正在使用vsnprintf(据我所知),但结果却很奇怪。我已将代码简化为以下示例:

void func(char *aaa, ...)
{
    char *buf;
    va_list args;
    int size;

    va_start(args, aaa);
    size = vsnprintf(NULL, 0, aaa, args)+1;
    buf = malloc(size);
    vsnprintf(buf, size, aaa, args);
    printf("%s",buf);
    free(buf);
    va_end(args);
}

int main(int argc, char **argv)
{
    func("abc %s", "def\n");
    return 0;
}

我希望打印“abc def”,但是我得到“abc”后跟一些垃圾文本。有没有人知道我搞砸了哪里?

2 个答案:

答案 0 :(得分:4)

当您将句柄args传递给vsnprintf()时,它将在您的案例中内部更改它。如果再次使用它将不会给出正确的参数。

如果您希望两次获取可选参数,请使用va_copy()创建args的副本。

void func(char *aaa, ...)
{
    char *buf;
    va_list args , argsc ;  //argsc is used in the second vsnprintf()
    int size;

    va_start(args, aaa);
    va_copy( argsc , args ) ; //make a copy of args
    size = vsnprintf(NULL, 0, aaa, args)+1;
    buf = malloc(size);
    vsnprintf(buf, size, aaa, argsc);  //use the copy since args is not valid
    printf("%s",buf);
    free(buf);
    va_end(args);
    va_end(argsc);  //destroy both
}

答案 1 :(得分:4)

va_start(args, aaa);
size = vsnprintf(NULL, 0, aaa, args)+1; // Reads all arguments
buf = malloc(size);
vsnprintf(buf, size, aaa, args); // Tries to read all arguments again
printf("%s",buf);
free(buf);
va_end(args);

参见注释行。您必须在消耗所有参数的两个调用之间重置args

插入:

va_end(args);
va_start(args, aaa);