How to add an argument to va_list
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 va_list
arg
before the call vsprintf()
because mine format
contains 1 additional argument at the end.
How do I add an argument (for example char * myarg
) to va_list
arg
?
Or is it possible to transfer a vsprintf()
customized list?
source to share
Unfortunately, there is no direct way to do this. There is a reason for this: stdarg macros pop the address onto the stack of the last known parameter, and then directly iterate the stack.
If you can use macros, @Useless has provided a nice solution - be careful, macros can have side effects when you pass variables before or after fixing them with ++
or --
.
If you want to avoid macros, you will have to write your own version of vsprintf. No problem for that, just find the source for the C stdlib ( GNU libc might be a good starting point) and be brave ... hope you can use macros!
source to share
You can not.
You either need to make two calls vsprintf
(of course vsnprintf
?), Or replace your function with a variable 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:
- I replaced
vsprintf
withvsnprintf
. There is no reason to use it here (or almost anywhere else). - you ignore
ret
. If you? - I have kept the layout of the macro argument similar to the original, but since it
__VA_ARGS__
must be one or more arguments (it cannot be empty), this means thatFMT
at least one argument is required after . Just remove theFMT
entire argument if you want to allow null arguments after it.
source to share