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

моя программа записывает в журнал и в stdout. Однако каждое сообщение имеет определенный приоритет, и пользователь указывает в настройках, какие приоритеты идут в какой поток (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) (возвращает >1, Если в обоих аргументах установлен флаг)

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

3 ответов


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

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

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


Я думаю, что идея Джеффа-это путь, но вы также можете выполнить это с помощью макроса без использования 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)