2009-10-04 2 views
13

Моя программа записывает в журнал и в стандартный вывод. Однако каждое сообщение имеет определенный приоритет, и пользователь указывает в настройках, какие приоритеты переходят к какому потоку (log или stdout).wrapper printf функция, которая фильтрует в соответствии с предпочтениями пользователя

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

Преференции обрабатывается некоторыми флагами:

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

write_log функция должна работать с теми же параметрами, что и функции PRINTF, с дополнительным параметром unsigned short priority.

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

(Даже если PRIO_NORMAL|PRIO_LOW имеет мало смысла ...)

Проверка флагов легко: if(priority & PRIO_LOG) (Returns> 1, если какой-либо флаг установлен в обоих аргументов)

я не могу, однако найти как я хотел бы передать строковый литерал и аргументы формата функции printf. Может ли кто-нибудь помочь или дать мне указатель (возможно альтернативный метод, который достигает такого же эффекта)? Это будет высоко ценится.

ответ

33

Вы хотите вызвать vprintf() вместо Е(), используя переменные аргументы «varargs» возможности 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); 
} 

Для получения дополнительной информации, увидеть что-то вдоль линий this.

+0

В Visual C++ вместо этого вы можете использовать _____VA_ARGS_____. Ссылка: http://msdn.microsoft.com/en-us/library/ms177415(v=vs.110).aspx –

+1

отредактируйте, чтобы показать требуемый '#include ' – robisrob

5

Я думаю, что идея Джеффа - это путь, но вы также можете выполнить это с помощью макроса без использования vprintf. Это может потребовать GCC:

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

Проверьте here для информации о том, как это работает.

4

Если вы хотите PRIO_ * Определения, которые будут использоваться в качестве бита (с использованием | и &), вы должны дать каждому из них свой собственный бит:

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

Макрос может быть улучшена за счет использования Д.О. {} в то время как (0) обозначение. Это делает вызовы write_log более похожим на инструкцию.

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

Извините, тип. Конечно, я сделал это в своем источнике. спасибо за указание! +1 для острого глаза. – wsd