printf 模仿slf4j 的log.xxx效果
- 简介
- 期待的效果
- 颜色
- 遇到的问题
- 实际的效果
- 代码实现
- 使用
- 效果图
简介
突然想玩一玩,能不能用printf实现slf4j里 的log.xxx 的效果。
性能是完全不考虑的,只要功能可用就好。
期待的效果
类似:info("这是第{}条日志",index);
颜色
一个好的日志打印,应当有对应的颜色。直接抄springboot 对应日志的默认配色。
遇到的问题
尝试使用c中的可变参数去实现,但是发现,可变是可变了,却不知道数据的类型。
而不知道数据的类型,printf 就没法打印。如果强行当做%s打印,那么解析铁定出错,因为它要找\0作为结束标签。
目前暂时没有找到办法,那就只能保留这个输出格式符,但是不要前面的%号。
比较,从键盘上看% 离的还挺远,不好找,可读性也比较差。
实际的效果
类似:info("这是第{d}条日志",index);
代码实现
util.h
#pragma once
void trace(const char * str, ...);
void debug(const char * str, ...);
void info(const char * str, ...);
void warn(const char * str, ...);
void error(const char * str, ...);
util.c
#include"util.h"
#include<stdio.h>
#include<stdarg.h>
#include<string.h>
#define ANSI_COLOR_RED "\033[31m"
#define ANSI_COLOR_GREEN "\033[32m"
#define ANSI_COLOR_YELLOW "\033[33m"
#define ANSI_COLOR_BLUE "\033[34m"
#define ANSI_COLOR_MAGENTA "\033[35m"
#define ANSI_COLOR_CYAN "\033[36m"
#define ANSI_COLOR_RESET "\033[0m"void resolveAndPrint(va_list args, const char * str);
/*带颜色的打印
*/
void printC(const char * color, const char * tag) {printf("%s%s%s", color, tag, ANSI_COLOR_RESET);}void trace(const char * str, ...) {printC(ANSI_COLOR_YELLOW, " [ TRACE ]: ");//声明va_list args;//初始化 va_start(args, str);//执行遍历resolveAndPrint(args, str);va_end(args);
}
void debug(const char * str, ...) {printC(ANSI_COLOR_YELLOW, " [ DEEBUG ]: ");//声明va_list args;//初始化 va_start(args, str);//执行遍历resolveAndPrint(args, str);//清理va_end(args);}
void info(const char * str, ...) {printC(ANSI_COLOR_CYAN, " [ INFO ]: ");//声明va_list args;//初始化 va_start(args, str);//执行遍历resolveAndPrint(args, str);//清理va_end(args);}
void warn(const char * str, ...) {printC(ANSI_COLOR_MAGENTA, " [ WARN ]: ");//声明va_list args;//初始化 va_start(args, str);//执行遍历resolveAndPrint(args, str);//清理va_end(args);}void error(const char * str, ...) {printC(ANSI_COLOR_RED, " [ ERROR ]: ");//声明va_list args;//初始化 va_start(args, str);//执行遍历resolveAndPrint(args, str);//清理va_end(args);
}void resolveAndPrint(va_list args, const char * str) {char * ch = str;char lastCh = 0;while (*ch != '\0'){if ((lastCh != '\\') && (*ch == '{' || *ch == '}')){lastCh = *ch;ch++;//跳过即可continue;}//匹配到类似 \\{ \\t \\n 这种,就直接输出原意 if ((lastCh == '\\')){printf("%c", *ch);lastCh = *ch;ch++;continue;}if (*ch == '\\'){lastCh = *ch;ch++;continue;}if (lastCh == '{') {//开始匹配参数了char symbol = *ch;//printf("symbol=%c \n", symbol);switch (symbol){case 's':printf("%s", va_arg(args, char *));break;case 'c':printf("%c", va_arg(args, char));break;case 'd':printf("%d", va_arg(args, int));break;case 'f':printf("%.2f", va_arg(args, double));break;default:printf("%c", symbol);break;}}else{printf("%c", *ch);}lastCh = *ch;ch++;}printf("\n");}
使用
main.c
#include<stdio.h>
#include"util.h"int main() {trace("小明今年{d}岁了 \\{\\} {s}给他祝贺,送了字母{c},体重{f}", 3,"小红",'B',57.3);debug("hhhh");info("hhhh");warn("hhhh");error("hhhh");return 0;
}