функция-обертка printf, которая фильтрует в соответствии с предпочтениями пользователя - PullRequest
16 голосов
/ 04 октября 2009

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

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

Ответы [ 3 ]

38 голосов
/ 04 октября 2009

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

6 голосов
/ 04 октября 2009

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

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

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

4 голосов
/ 05 октября 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)
...