Tengo el siguiente código:
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; } Quiero agregar un argumento al argumento va_list antes de llamar a arg vsprintf() porque mi format contiene 1 argumento adicional al final.
¿Cómo agregar un argumento (por ejemplo char * myarg ) al arg va_list ?
¿O es posible pasar vsprintf() una lista personalizada?
no puedes
O necesita hacer dos vsprintf (¿seguramente vsnprintf ?), o reemplazar su función con una macro variable, como
#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; }Notas:
vsprintf con vsnprintf . No hay razón para usar el primero aquí (o prácticamente en cualquier otro lugar)ret . ¿Deberías?__VA_ARGS__ debe ser uno o más argumentos (no puede estar vacío), eso significa que se requiere al menos un argumento después de FMT . Simplemente elimine el argumento FMT por completo si desea permitir cero argumentos después de él.Desafortunadamente, no hay una forma directa de hacerlo. Hay una razón para eso: las macros stdarg toman la dirección en la pila del último parámetro conocido y luego iteran directamente la pila.
Si puede usar macros, @Useless brindó una buena solución: tenga cuidado, las macros pueden tener efectos secundarios cuando pasa variables pre o posfijadas con ++ o -- .
Si desea evitar las macros, deberá escribir su propia variante de vsprintf. No hay problema, solo busque una fuente para C stdlib ( GNU libc podría ser un buen punto de partida) y sea valiente ... ¡espero que pueda usar macros!