2010-01-13 22 views
22

Duplicar posibles:
C Programming: Forward variable argument list.¿Es posible escribir una función varargs que envíe su lista de argumentos a otra función varargs?

Lo que me gustaría hacer es enviar los datos a una biblioteca de registro (que no puedo modfify) en una especie de printf manera.

así que me gustaría una función algo como esto:

void log_DEBUG(const char* fmt, ...) { 
    char buff[SOME_PROPER_LENGTH]; 
    sprintf(buff, fmt, <varargs>); 
    log(DEBUG, buff); 
} 

¿Puedo pasar a otra función varargs vararg de alguna manera?

+1

Dupe: http://stackoverflow.com/questions/1719784/c-programming-forward-variable-argument-list –

Respuesta

25

No se puede reenviar la lista de argumentos variables, ya que no hay manera de expresar lo que hay debajo de ... como parámetro (s) de otra función.

Sin embargo se puede construir un va_list partir de los parámetros ... y enviar que a la función que se formatearlo correctamente. Esto es para lo que vsprintf es. Ejemplo:

void log_DEBUG(const char* fmt, ...) { 
    char buff[SOME_PROPER_LENGTH]; 
    va_list args; 
    va_start(args, fmt); 
    vsprintf(buff, fmt, args); 
    va_end(args); 
    log(DEBUG, buff); 
} 
+1

No se olvide ** va_end ** –

+0

@Nikolai N Fetissov: Gracias, corregido. –

+3

No veo nada no estándar aquí. –

3

No en C++ estándar.

+0

derecho, en C++ sería preferible usar '<<' – ezpz

7

Es por eso que usted tiene la familia de funciones vprintf.

4

Para su requisito específico, puede usar vsprintf. Mi C/C++ está demasiado oxidado para recordar si hay una manera directa de hacerlo cuando la otra función no está diseñada para eso (sin entrar en la fea manipulación de la pila), pero tiendo a pensar que no.

13

Puede enviarlo a otra función que tome una va_list como argumento. No hay otra manera, salvo recurrir a un asm hecho a mano, o hacer algún tipo de juego de adivinanzas horripilante para descubrir el 'número' de parámetros.

Esto funcionaría:

void log_DEBUG(const char* fmt, ...) 
{ 
    va_list va; 
    va_start(va,fmt); 
    char buff[blah]; 
    vsprintf(buff,fmt,va); 
    log(DEBUG,buff); 
    va_end(va); 
} 

Básicamente, cada vez que se escribe una función que toma ..., usted debe escribir otra versión que lleva un va_list - su la cosa educada a hacer si desea habilitar esta tipo de llamada de encadenamiento

+0

Exactamente lo que necesitaba Estaba pensando que tal vez había alguna manera de pasar la lista de argumentos directamente, ¡pero a vsprintf le iría bien! –

+0

la respuesta aceptada se perdió el punto "vsprintf" por lo que mucha gente (inc me) buscará esta respuesta en Google. – perfectionist

Cuestiones relacionadas