2009-10-04 11 views
13

Mon programme écrit dans un journal et dans stdout. Chaque message, cependant, a une certaine priorité et l'utilisateur spécifie dans les préférences quelles priorités vont à quel flux (log ou stdout).Fonction wrapper printf qui filtre selon les préférences de l'utilisateur

unsigned short PRIO_HIGH = 0x0001; 
unsigned short PRIO_NORMAL = 0x0002; 
unsigned short PRIO_LOW = 0x0003; 

Les préférences sont gérées par des drapeaux:

unsigned short PRIO_LOG = (PRIO_HIGH | PRIO_NORMAL); 
unsigned short PRIO_STD = (PRIO_HIGH); 

La fonction write_log devrait fonctionner avec les mêmes paramètres que la fonction printf, avec le paramètre supplémentaire de unsigned short priority.

write_log((PRIO_NORMAL|PRIO_LOW), "HELLO %s, take %d", "World", 1); 

(Même si PRIO_NORMAL|PRIO_LOW peu de sens ...)

Vérification des drapeaux est facile: if(priority & PRIO_LOG) (Retours> 1 si un indicateur est défini dans les deux arguments)

je ne peux cependant trouver comment je vais passer le littéral chaîne et les arguments de format à la fonction printf. Quelqu'un peut-il m'aider ou me donner un pointeur (possible à une méthode alternative qui réalise le même effet)? Cela serait très appréciable.

Répondre

33

Vous voulez appeler vprintf() au lieu de printf() en utilisant les arguments variables "varargs" des capacités de C.

int write_log(int priority, const char *format, ...) 
{ 
    va_list args; 
    va_start(args, format); 

    if(priority & PRIO_LOG) 
      vprintf(format, args); 

    va_end(args); 
} 

Pour plus d'informations, voir quelque chose le long des lignes de this.

+0

En Visual C++, vous pouvez utiliser _____VA_ARGS_____ à la place. Référence: http://msdn.microsoft.com/en-us/library/ms177415(v=vs.110).aspx –

+1

s'il vous plaît modifier pour afficher requis '#include ' – robisrob

5

Je pense que l'idée de Jeff est la voie à suivre, mais vous pouvez aussi accomplir ceci avec une macro sans utiliser vprintf. Cela pourrait nécessiter gcc:

#define write_log(priority,format,args...)  \ 
        if (priority & PRIO_LOG) {  \ 
         printf(format, ## args); \ 
        } 

Vérifiez here pour plus d'informations sur la façon dont cela fonctionne.

4

Si vous voulez que les PRIO_ * définitions à utiliser comme bit (en utilisant | et &), vous devez donner à chacun d'eux son propre bit:

unsigned short PRIO_HIGH = 0x0001; 
unsigned short PRIO_NORMAL = 0x0002; 
unsigned short PRIO_LOW = 0x0004; 

La macro peut être améliorée en utilisant le do {} en notation (0). Il fait que les appels à write_log agissent plus comme une déclaration.

#define write_log(priority,format,args...) do { \ 
    if (priority & PRIO_LOG) { \ 
     printf(format, ## args); \ 
    } while(0) 
+0

Désolé, tapez. Je l'ai fait comme ça dans ma source bien sûr. merci pour le fait remarquer! +1 pour un œil vif. – wsd