C++:标准日志函数
我们写日志函数通常有以下几个要求:
- 日志等级
- 自定义输入内容
- 输入内容可以进行格式控制
- 可以使用宏定义控制的日志
有关内容已经在我上一篇写的文章中发过了,除了格式控制,已经基本实现了其他功能,这期主要来补全一下格式控制这块:
怎么进行格式控制呢?这里我使用了C语言的vprintf
函数:
vprintf
函数是 C 标准库中的一个功能强大的函数,用于将格式化的输出发送到标准输出(stdout
)。让我们来详细了解一下 vprintf
的用法:
-
函数声明:
int vprintf(const char *format, va_list arg);
-
描述:
vprintf
函数使用参数列表发送格式化输出到标准输出(stdout
)。它的工作方式类似于printf
,但是使用由arg
标识的可变参数列表中的元素来替换格式说明符,而不是附加的函数参数。在内部,函数从arg
标识的列表中检索参数,就好像使用了va_arg
一样,因此arg
的状态可能会被调用所改变。 -
参数:
format
:这是一个字符串,包含要写入到标准输出(stdout
)的文本。它可以包含嵌入的格式标签,这些标签会被随后的附加参数中指定的值替换,并按需进行格式化。格式标签的属性包括%[flags][width][.precision][length]specifier
,具体说明如下:specifier
:输出的类型,例如字符、整数、浮点数等。flags
:标识,例如对齐方式、是否显示正号等。width
:输出的最小字符数。.precision
:小数点后的位数。length
:参数的长度,例如短整型、长整型等。
arg
:一个表示可变参数列表的对象,应该由<stdarg.h>
中定义的va_start
宏初始化。
-
返回值:
- 如果成功,则返回写入的字符总数,否则返回一个负数。
-
示例:
下面的示例演示了vprintf
函数的用法:#include <stdio.h> #include <stdarg.h>void WriteFormatted(char *format, ...) {va_list args;va_start(args, format);vprintf(format, args);va_end(args); }int main() {WriteFormatted("%d variable argument\n", 1);WriteFormatted("%d variable %s\n", 2, "arguments");return 0; }
运行上述程序将产生以下输出:
1 variable argument 2 variable arguments
请注意,vprintf
函数通常与 va_start
和 va_end
配套使用,而在大多数情况下,输出到控制台时直接使用 printf
函数即可。只有在需要自定义 printf
函数时,才需要使用 vprintf
函数。
下面是我的日志函数:
#include <stdio.h>
#include <stdarg.h>#define LOG_LEVEL_INFO 0
#define LOG_LEVEL_WARNING 1
#define LOG_LEVEL_ERROR 2void log_event(int level, const char *filename, const char *format, ...){time_t now = time(NULL);char *level_str;FILE *fp;va_list args;switch(level) {case LOG_LEVEL_INFO: {level_str = "INFO";break;}case LOG_LEVEL_WARNING: {level_str = "WARNING";break;}case LOG_LEVEL_ERROR : {level_str = "ERROR";break;}default: {level_str = "UNKNOWN";break;}}fp = fopen(filename, "a");if(fp == NULL) {perror("Open file ERROR!");return ;}if(fp != NULL) {fprintf(fp, "%s [%s]: ", ctime(&now), level_str);va_start(args, format);vfprintf(fp, format, args);va_end(args);fprintf(fp, "\n");fclose(fp);}return ;
}