我有以下代码:
int __dmasprintf (char **s, const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsprintf(buf, format, arg);
va_end(arg);
*s = strdup(buf);
if (*s == NULL) return -1;
return 0;
}
我想在调用va_list
之前向arg
vsprintf()
添加一个参数,因为我的format
最后包含1个额外的参数。
如何将参数(例如char * myarg
)添加到va_list
arg
?
或者是否可以通过vsprintf()
自定义列表?
答案 0 :(得分:5)
你不能。
您需要制作两个vsprintf
(肯定是 vsnprintf
?)调用,或者使用可变参数宏替换您的函数,例如
#define __dmasprintf(S, FMT, ...) ( \
(*S = do_dmasprintf(FMT, __VA_ARGS__, my_arg)) == NULL ? -1 : 0)
char *do__dmasprintf (const char *format, ...) {
char buf[512];
va_list arg;
int ret;
va_start(arg,format);
ret = vsnprintf(buf, sizeof(buf), format, arg);
va_end(arg);
char *s = strdup(buf);
return s;
}
注意:
vsprintf
替换为vsnprintf
。没有理由在这里使用前者(或其他任何地方)ret
。你呢?__VA_ARGS__
必须是一个或多个参数(它不能为空),这意味着{{1}后需要至少一个参数}}。如果要在其后允许零参数,则完全删除FMT
参数。答案 1 :(得分:1)
遗憾的是,没有直接的方法可以做到这一点。有一个原因:stdarg宏获取最后一个已知参数的堆栈中的地址,然后直接迭代堆栈。
如果您可以使用宏,@ Useless提供了一个很好的解决方案 - 请注意,当您使用++
或--
预先或后修复变量时,宏可能会产生副作用。
如果您想避免使用宏,则必须编写自己的vsprintf变体。没问题,只需找到C stdlib的源代码(GNU libc可能是个不错的起点)并且勇敢...希望你能使用宏!