我正在编写一个日志编写器,为此我在vfprintf上编写了一个包装函数,因此我可以在它周围添加一些额外的信息。
日志写入宏定义如下:
#define LOG_WRITE(type, fmt, args...) write_log(type, __FILE__, __FUNCTION__, __LINE__, fmt, ## args)
我的功能定义如下:
int write_log(enum LogType_e type, const char* file, const char* function, int line, const char* format, ...) {
va_list arg;
int rv;
va_start(arg, format);
rv = vfprintf(log_fd, format, arg);
va_end(arg);
return rv;
}
该函数获取一些额外信息,例如日志级别,运行日志调用的文件,函数,代码行,最后是文本。
当然,我想检查一下这些信息并将其格式化,并将其添加到“格式”中。我怎么能这样做?
答案 0 :(得分:1)
最简单的解决方案可能不是摆弄格式字符串,而是添加对fprintf(log_fd, ...)
的进一步调用:
void write_log(enum LogType_e type, const char* file, const char* function, int line, const char* format, ...) {
va_list arg;
int rv;
switch (type) {
case TYPE_ERROR:
fprintf(log_fd, "Error: ");
break;
case TYPE_WARN:
fprintf(log_fd, "Warning: ");
break;
}
if (file) {
if (function) {
fprintf(log_fd, "[%s in %s, %d] ", function, file, line);
} else {
fprintf(log_fd, "[%s, %d] ", file, line);
}
}
va_start(arg, format);
rv = vfprintf(log_fd, format, arg);
va_end(arg);
}
这使得跟踪打印的字符数量变得更加困难,但您无论如何都不会使用该信息,因此计算和返回它是没有意义的。
(你也可以登录一个临时字符串,如果你需要自动换行,那么就打印出来。但这意味着你必须再次跟踪整个字符串的长度。)
答案 1 :(得分:0)
修改fprintf
语句以满足您所需的输出。请注意,下面的示例使用__VA_ARGS__
,它是处理可变参数AFAIK的C预处理器方式。
#define LOG_WRITE(type, fp, fmt, ...) write_log(type, fp, __FILE__, __FUNCTION__, __LINE__, fmt,##__VA_ARGS__)
int write_log(enum LogType_e type, FILE *fp, const char *file, const char* function, int line, const char* format, ...)
{
va_list arg;
int rv;
va_start(arg, format);
fprintf(fp, "file %s:function %s:line %d:", file, function, __LINE__);
rv = vfprintf(fp, format, arg);
va_end(arg);
return rv;
}
int main()
{
FILE* fp = fopen("test.log", "w");
int b = 13, c = 5;
write_log(LOG_ERROR, fp, "vfprintf.c", "main", 27, "%s %d\n", "value of b=", b);
LOG_WRITE(LOG_ERROR, fp, "value of c=%d\n", c);
LOG_WRITE(LOG_ERROR, fp, "help!!\n");
}