【问题标题】:wrapper printf function that filters according to user preferences根据用户偏好过滤的包装器 printf 函数
【发布时间】:2010-12-03 17:38:15
【问题描述】:

我的程序写入日志和标准输出。然而,每条消息都有一个特定的优先级,用户在 Preferences 中指定哪些优先级转到哪个流(日志或标准输出)。

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 函数。任何人都可以帮助或给我一个指针(可能是达到相同效果的替代方法)?将不胜感激。

【问题讨论】:

    标签: c filter printf wrapper


    【解决方案1】:

    您想使用 C 的可变参数“varargs”功能调用 vprintf() 而不是 printf()。

    #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

    【讨论】:

    【解决方案2】:

    我认为 Jeff 的想法是可行的方法,但您也可以使用宏而不使用 vprintf 来完成此操作。这可能需要 gcc:

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

    查看here 了解其工作原理。

    【讨论】:

      【解决方案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)
      

      【讨论】:

      • 抱歉,键入。我当然是在我的源代码中这样做的。感谢您的指出! +1 敏锐的眼光。
      猜你喜欢
      • 2013-05-25
      • 1970-01-01
      • 2013-04-11
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      相关资源
      最近更新 更多