在下面的程序中,可变函数process_message
通过va_list argp
参数将其变量参数传递给print_message
。 argp
又传递给vsnprintf
,后者计算格式字符串的长度。
但是,如果将argp
传递给从print_message
内调用的另一个函数,例如vprintf(fmt, argp)
,则会产生无意义的输出。是否可以使用va_list
参数的函数多次使用它?
#include <stdio.h>
#include <stdarg.h>
void process_message(const char *fmt, ...);
void print_message(const char *fmt, va_list argp);
int main(void) {
process_message("%s:%d\n", "test message", 1);
return 0;
}
void process_message(const char *fmt, ...) {
va_list argp;
va_start(argp, fmt);
print_message(fmt, argp);
va_end(argp);
}
void print_message(const char *fmt, va_list argp) {
/*Calculate and print the length of the format string*/
int len = vsnprintf(NULL, 0, fmt, argp);
printf("Length of format string = %d\n", len);
/*Print the rendered format string - this produces a nonsense output
*if argp was aleady passed to another function earlier */
vprintf(fmt, argp);
}
答案 0 :(得分:6)
您可以使用va_copy
:
va_copy()宏将(先前初始化的)变量参数列表src复制到dest。行为就好像va_start()应用于具有相同最后一个参数的dest,后跟用于达到当前src状态的相同数量的va_arg()调用。
你print_message()
可能是:
void print_message(const char *fmt, va_list argp) {
/*Calculate and print the length of the format string*/
va_list argp_copy;
va_copy(argp_copy, argp);
int len = vsnprintf(NULL, 0, fmt, argp_copy);
va_end(argp_copy);
printf("Length of format string = %d\n", len);
/*Print the rendered format string - this produces a nonsense output
*if argp was aleady passed to another function earlier */
vprintf(fmt, argp);
}
注意:强>
使用复制的va_end
后,请不要忘记致电va_list
。
C11:
va_start和va_copy宏的每次调用都应与同一函数中va_end宏的相应调用相匹配。