2009-10-04 8 views
13

Mi programa escribe en un registro y en stdout. Sin embargo, cada mensaje tiene una cierta prioridad y el usuario especifica en Preferencias qué prioridades van a qué flujo (log o stdout).envoltura printf función que se filtra según las preferencias del usuario

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

Las preferencias es manejado por algunas banderas:

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

La función write_log debe trabajar con los mismos parámetros que la función printf, con el parámetro adicional de unsigned short priority.

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

(Incluso si PRIO_NORMAL|PRIO_LOW tiene mucho sentido ...)

Comprobación de las banderas es fácil: if(priority & PRIO_LOG) (Vuelve> 1 si algún indicador se establece en los dos argumentos)

no puedo encontrar sin embargo cómo voy a pasar la cadena literal y los argumentos de formato a la función printf. ¿Alguien puede ayudarme o darme un puntero (posible a un método alternativo que logra el mismo efecto)? Sería muy apreciado.

Respuesta

33

que desea llamar vprintf() en lugar de printf() con los argumentos variables "varargs" capacidades 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); 
} 

Para más información, ver algo en la línea de this.

+0

En Visual C++ puede usar _____VA_ARGS_____ en su lugar. Referencia: http://msdn.microsoft.com/en-us/library/ms177415(v=vs.110).aspx –

+1

por favor edítelo para mostrar el requerido '#include ' – robisrob

5

Creo que la idea de Jeff es el camino a seguir, pero también puede lograr esto con una macro sin usar vprintf. Esto podría requerir gcc:

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

Comprobar here para obtener información acerca de cómo funciona esto.

4

Si desea que los PRIO_ * definiciones que se utilizan como bits (usando | y &), debe dar a cada uno de ellos su propio bits:

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

La macro se puede mejorar mediante el uso de la DO {} while (0) notación. Hace que las llamadas a write_log actúen más como una declaración.

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

Disculpe, escriba. Lo hice así en mi fuente, por supuesto. gracias por el señalamiento! +1 para un ojo agudo. – wsd

Cuestiones relacionadas