wrapper printf, которая фильтрует в соответствии с пользовательскими настройками

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

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. Может ли кто-нибудь помочь или дать мне указатель (возможно альтернативный метод, который достигает такого же эффекта)? Это будет высоко ценится.

Вы хотите вызвать vprintf () вместо printf (), используя переменные аргументы « varargs » возможностей C.

 #include  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); } 

Для получения дополнительной информации см. Что-то вроде этого .

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

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

Здесь вы можете узнать, как это работает.

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

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

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

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