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