我知道在C99(以及通过GNU扩展)中添加了可变参数宏。我一直想知道ANSI C中是否有一个不错的选择。
我想出了类似的东西,但它仍然有点尴尬:
void log_info(const char *file, int line, const char *fmt, ...)
{
#ifdef DEBUG
va_list ap;
char newfmt[1024] = { 0 };
va_start(ap, fmt);
sprintf(newfmt, "[INFO] (%s:%d): %s\n", file, line, fmt);
vfprintf(stderr, newfmt, ap);
va_end(ap);
#endif
}
这样就可以这样调用:
log_info(__FILE__, __LINE__, "info message: %s %d", "helloworld", 12);
这种方法没有错,但是我想知道是否有更好的方法呢?例如。无需每次都指定文件/行。
我很感激任何反馈。 :)
编辑:按ANSI C,我的意思是C89。
编辑:下面的答案很好,但我相信它需要运行打印命令twise,它可能会带来一些线程安全问题。另一种选择可能是使用define来最小化输入(也非常难看):
#define __FL__ __FILE__, __LINE__
然后运行命令:
log_info(__FL__, "info message: %s %d", "helloworld", 12);
答案 0 :(得分:16)
它有点难看,但括号中的逗号分隔表达式序列可以视为单个参数。
一个例子:
#include <stdio.h>
#define LOG(args) (printf("LOG: %s:%d ", __FILE__, __LINE__), printf args)
int main(void) {
LOG(("Hello, world\n"));
int n = 42;
LOG(("n = %d\n", n));
return 0;
}
输出:
LOG: c.c:6 Hello, world
LOG: c.c:8 n = 42
请注意,这需要在呼叫中添加一组额外的括号。
答案 1 :(得分:3)
这是一个更加丑陋的选项,但是使用单一调用printf:
#define PROMPT "[INFO] (%s:%d): "
#define FL __FILE__, LINE__
#define DEBUG0(fmt) printf(PROMPT fmt, FL);
#define DEBUG1(fmt, a1) printf(PROMPT fmt, FL, a1);
#define DEBUG2(fmt, a1, a2) printf(PROMPT fmt, FL, a1, a2);
#define DEBUG3(fmt, a1, a2, a3) printf(PROMPT fmt, FL, a1, a2, a3);
等等,直到用宏调用宏的大多数参数。