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


person wsd    schedule 04.10.2009    source источник


Ответы (3)


Вы хотите вызвать 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);
}

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

person Tall Jeff    schedule 04.10.2009
comment
В Visual C ++ вместо этого можно использовать _____VA_ARGS_____. Ссылка: msdn.microsoft.com/en-us /library/ms177415(v=vs.110).aspx - person Helge Klein; 20.11.2013

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

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

Информацию о том, как это работает, можно найти здесь.

person John Ledbetter    schedule 04.10.2009

Если вы хотите, чтобы определения 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)
person eyalm    schedule 05.10.2009
comment
Извините, Тип. Я, конечно, так и сделал в своем источнике. спасибо за указание! +1 за зоркий глаз. - person wsd; 05.10.2009