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?

+3


source to share


2 answers


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!

+1


source


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

    with vsnprintf

    . 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 that FMT

    at least one argument is required after . Just remove the FMT

    entire argument if you want to allow null arguments after it.
+5


source







All Articles