Reputation: 43518
I have the following code:
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;
}
I want to add an argument to the va_list
arg
before calling vsprintf()
because my format
contains 1 extra argument at the end.
How to add an argument (for example char * myarg
) to the the va_list
arg
?
Or is it possible to pass vsprintf()
a customized list?
Upvotes: 8
Views: 9476
Reputation: 67713
You can't.
You either need to make two vsprintf
(surely vsnprintf
?) calls, or replace your function with a variadic macro, like
#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;
}
Notes:
vsprintf
with vsnprintf
. There's no reason to use the former here (or pretty much anywhere else)ret
. Should you?__VA_ARGS__
must be one-or-more arguments (it can't be empty), that means at least one argument is required after FMT
. Just remove the FMT
argument entirely if you want to allow zero arguments after it.Upvotes: 8
Reputation: 148880
There is unfortunately no direct way to do that. There is a reason for that : the stdarg macros take the address in the stack of the last known parameter, and then directly iterate the stack.
If you can use macros, @Useless provided a nice solution - beware, macros can have side effects when you pass variables pre- or post-fixed with ++
or --
.
If you want to avoid macros, you will have to write your own variant of vsprintf. No problem for it, just find a source for C stdlib (GNU libc could be a nice start point) and be brave ... hope you can use macros !
Upvotes: 2