我正在使用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”后跟一些垃圾文本。有没有人知道我搞砸了哪里?
答案 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);