根据用户偏好过滤的包装器 printf 函数
Posted
技术标签:
【中文标题】根据用户偏好过滤的包装器 printf 函数【英文标题】:wrapper printf function that filters according to user preferences 【发布时间】: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 函数。任何人都可以帮助或给我一个指针(可能是达到相同效果的替代方法)?将不胜感激。
【问题讨论】:
【参考方案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。
【讨论】:
在 Visual C++ 中,您可以改用 _____VA_ARGS____。参考:msdn.microsoft.com/en-us/library/ms177415(v=vs.110).aspx【参考方案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 敏锐的眼光。以上是关于根据用户偏好过滤的包装器 printf 函数的主要内容,如果未能解决你的问题,请参考以下文章
《Head First Servlets & JSP》-13-过滤器和包装器
swift ImageFilter hold一个全局的图片处理注册器,可以注册一些图片处理函数。然后ImageFilter数据结构包装一个要处理的图片的信息,通过这个包装方便的对一个图片应用某个过滤器