Подтвердить что ты не робот

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

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

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

Предпочтения обрабатываются некоторыми флагами:

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) (Возвращает> 1, если какой-либо флаг установлен в обоих аргументах)

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

4b9b3361

Ответ 1

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

#include <stdarg.h>

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

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

Ответ 2

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

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

Обратитесь здесь для получения информации о том, как это работает.

Ответ 3

Если вы хотите, чтобы определения 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)