2009-11-12 23 views
39

J'essaye d'écrire une fonction qui accepte un nombre variable de paramètres comme printf, fait des choses, puis passe la liste des variables à printf. Je ne suis pas sûr de savoir comment faire cela, car il semble que cela devrait les pousser sur la pile.C Programmation: Liste d'arguments de variable directe

Quelque chose à peu près comme celui-ci

http://pastie.org/694844

#include <stdio.h> 
#include <stdarg.h> 

void forward_args(const char *format , ...){ 
    va_list arglist; 
    printf(format, arglist); 
} 


int main (int argc, char const *argv[]){ 
    forward_args("%s %s\n" , "hello" , "world"); return 0; 
} 

Toutes les idées?

+4

Peut-être que John et vous êtes dans la même classe? http://stackoverflow.com/questions/1714550/how-can-one-variable-args-function-call-another –

+2

duplication possible de [Transférer une invocation d'une fonction variadique en C] (http://stackoverflow.com/questions/150543/forward-an-invocation-of-a-variadic-function-in-c) – dmckee

Répondre

49

Ne pas transmettre les résultats à printf. passez-les au vprintf. vprintf existe spécifiquement pour gérer le passage des arguments va_list. A partir de la page de manuel Linux:

#include <stdio.h> 

int printf(const char *format, ...); 
int fprintf(FILE *stream, const char *format, ...); 
int sprintf(char *str, const char *format, ...); 
int snprintf(char *str, size_t size, const char *format, ...); 

#include <stdarg.h> 

int vprintf(const char *format, va_list ap); 
int vfprintf(FILE *stream, const char *format, va_list ap); 
int vsprintf(char *str, const char *format, va_list ap); 
int vsnprintf(char *str, size_t size, const char *format, va_list ap); 

Remarquez comment ces derniers prennent explicitement va_list des arguments tels que ceux que vous déclarez dans une fonction prise ... dans la liste des paramètres. Donc, votre fonction serait déclarée comme ceci:

void forward_args(const char *format , ...){ 
    va_list arglist; 
    va_start(arglist, format); 
    vprintf(format, arglist); 
    va_end(arglist); 
} 
+1

Eh bien, il a besoin de 'va_start()' et 'va_end()' aussi. –

+0

@Ken Bloom: Vous avez raison. Fixé. – quark

+4

'va_start (arglist, format)' –

2

Vous allez passer la valeur arglist à une fonction conçue pour la consommer. Voir la documentation stdarg et vprintf pour plus d'indices.

-1

Je ne suis pas (au-dessus de ma tête) familier avec la façon de mettre en œuvre cela. Je suggère de regarder une implémentation de fonctions comme printf. Plusieurs implémentations open source existent. glibc, uclibc (pas sûr de ce que bsd et opensolaris appellent/utilisent pour leur libc).

3

Je suis sûr que vous êtes à la recherche va_start()/vprintf()/vsnprintf()/va_end(), il n'y a pas besoin de mettre en œuvre ces soi-même.