我有很多函数,在输入每个函数时,我调用的是一个宏FUNC_ENTRY,它又调用默认的日志记录宏(LOGGING)。
具体来说,这是我的FUNC_ENTRY宏:
#define FUNC_ENTRY LOGGING(ONE, "Entry");
我的LOGGING宏定义如下:
#define LOGGING(prio, my_var, ...) \
{\
char priority[6];\
bzero(level,4); \
if (prio == ONE) { sprintf(priority,"ONE");} \
if (prio == TWO) { sprintf(priority,"TWO");} \
if (prio == THREE) { sprintf(priority,"THREE");} \
fprintf(fp,"%s: %s: %s: %d: %s:%s|\n",__DATE__, __TIME__, __FILE__,__LINE__, __func__,level);\
fflush(fp); \
fprintf(fp,my_var,##__VA_ARGS__);\
fflush(fp); \
fprintf(fp,"\n");\
fflush(fp); \
}
好的,现在我的问题是,每当我输入任何功能时,我的LOGGING宏应该打印"输入xyz功能"。截至目前,它只打印" Entry"。任何线索如何实现这一目标?
我调用FUNC_ENTRY宏的方式如下所示。 假设我有一个函数xyz;
void xyz {
FUNC_ENTRY;
/*other statements*/
}
答案 0 :(得分:3)
有很多问题:
除非您认为经常编写有缺陷的代码,否则大多数目的都会有两个fflush(fp)
次调用。
'奇怪的是,您将level
归零,声明并设置priority
,但打印level
仍为全零。
该片段足以保证功能。
您不希望在#define FUNCENTRY
之后使用分号。
'如果您未在宏中的字符串中包含Entry to xyz function
或to
,您认为应该function
,这也很奇怪。
在您的错误消息中编译文件的时间和日期似乎毫无意义(__DATE__
和__TIME__
是针对的)。
修复其中一些问题会导致:
#define FUNC_ENTRY LOGGING(ONE, "Entry to %s function\n", __func__)
#define LOGGING(prio, my_var, ...) \
{\
char priority[6];\
memset(priority, '\0', sizeof(priority)); \
if (prio == ONE) { sprintf(priority, "ERR");} \
if (prio == TWO) { sprintf(priority, "TWO");} \
if (prio == THREE) { sprintf(priority, "THREE");} \
fprintf(fp,"%s: %s: %s: %d: %s:%s|\n", __DATE__, __TIME__, __FILE__, __LINE__, __func__, priority);\
fprintf(fp, my_var, ##__VA_ARGS__); \
fprintf(fp,"\n"); \
fflush(fp); \
}
我注意到, ##__VA_ARGS__
是标准C上的GCC扩展。bzero()
函数在POSIX 2004中被标记为过时,并且在POSIX 2008中缺失;最好不要使用它。
目前尚不清楚,但从代码判断,您有一个全局(或至少是文件范围)变量FILE *fp;
,它被初始化为您要写入的日志文件。伊克;同样哎呀!
如果是我的代码(我想要拼写Entry to xyz function
消息),我可能会使用:
extern void err_logger(int level, int line, char const *file, char const *func, ...);
和
#define FUNC_ENTRY LOGGING(ONE, "Entry to %s function\n", __func__)
#define LOGGING(prio, ...) \
err_logger(level, __LINE__, __FILE__, __func__, __VA_ARGS)
err_logger()
的实施可能是:
void err_logger(int level, int line, char const *file, char const *func, ...)
{
char *priority = "";
if (level == ONE) priority = "ERR";
if (level == TWO) priority = "TWO";
if (level == THREE) priority = "THREE";
time_t t = time(0);
char date_time[32];
strftime(date_time, sizeof(date_time), "%Y-%m-%d %H:%M:%S", gmtime(&t));
fprintf(logfp, "%s: %s: %d: %s: %s|\n", date_time, file, line, func, priority);
va_list args;
va_start(args, func);
char *fmt = va_arg(args, char *);
vfprintf(logfp, fmt, args);
va_end(args);
fflush(logfp);
}
logfp
将成为日志文件流,并且对于保存err_logger()
源的文件是私有的。
我没有编译那段代码;可能会有一些小错误。但是,它确实为您提供了如何操作以及如何操作的一般概念 - 我认为。
答案 1 :(得分:1)
这些方面的东西:
#include <stdio.h>
#define T printf("Entering %s\n", __func__)
int main(void)
{
T;
return 0;
}
不幸的是,您似乎无法在编译时将其连接到您的字符串(请参阅此处:Can I substitute __func__ into an identifier name in a C macro?)。可能有一些其他编译器特定或C ++特定的技巧,但否则你将需要在运行时构建你的字符串。