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?
The va_start macro enables access to the variable arguments following the named argument parm_n . va_start should be invoked with an instance to a valid va_list object ap before any calls to va_arg.
va_list is a complete object type suitable for holding the information needed by the macros va_start, va_copy, va_arg, and va_end. If a va_list instance is created, passed to another function, and used via va_arg in that function, then any subsequent use in the calling function should be preceded by a call to va_end.
NULL in general case is not a valid initializer for a va_list object. So, the answer to your question is: it is not possible.
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.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 !
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With