printf 模仿slf4j 的log.xxx效果

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;
}

效果图

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/15153.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ffmpeg-webrtc(metartc)给ffmpeg添加webrtc协议

这个是使用metrtc的库为ffmpeg添加webrtc传输协议&#xff0c;目前国内还有一个这样的开源项目&#xff0c;是杨成立大佬&#xff0c;大师兄他们在做&#xff0c;不过wili页面维护的不好&#xff0c;新手不知道如何使用&#xff0c;我专门对它做过介绍&#xff0c;另一篇博文&a…

不同类型水表计量技术的优缺点

1.单流束水表 1.1优点 (1)耐受悬浮固体。适用于硬水或悬浮颗粒物。 (2)多样性&#xff0c;可用性&#xff0c;容易找到需要的合适的表型。 (3)技术可靠&#xff0c;已使用了数十年。 (4)体积小&#xff0c;可以安装在狭小的空间里。 (5)13mm、15mm、20mm水表可能是市面…

CTFHUB技能树——SSRF(二)

目录 上传文件 ​FastCGI协议 Redis协议 上传文件 题目描述&#xff1a;这次需要上传一个文件到flag.php了.祝你好运 index.php与上题一样&#xff0c;使用POST请求的方法向flag.php传递参数 //flag.php页面源码 <?phperror_reporting(0);if($_SERVER["REMOTE_ADDR&…

Java面向对象程序设计-集合容器(toString方法)

以下是翁恺老师3.3.1集合容器的示范代码&#xff1a; class Value{ private int i; public void set(int i){this.ii;}public int get(){return i;}public String toString(){return ""i; } //注意这句的有无 }public class NoteBook {public static void ma…

python --- 第19课 面对对象(上)--- 纯干货

面对对象 程序是由数据和功能组合而成的对象构建起来的&#xff0c;对数据与函数绑定到一起&#xff0c;进行封装&#xff0c;能够更快速的开发程序&#xff0c;减少重复代码 class --- 类&#xff0c;类是对象的抽象化&#xff0c;具有相同特征或行为的事物的统称 类的定义…

npm 上传包

将自己做好的包做好后上传 1. 切换镜像&#xff08;只能通过官网代理来上传&#xff09; npm config set registry https://registry.npmjs.org/ 2. 添加用户&#xff08;等价登录&#xff09; npm addUser 3. 提交 npm publish 4. 删除 npm unpublish [<pkg>][&…

呼叫中心软件:轻松应对高峰时段,保障服务质量

一、引言 在当今竞争激烈的市场环境中&#xff0c;客户服务已经成为企业成功的重要因素之一。呼叫中心作为客户服务的重要渠道&#xff0c;承载着企业与客户之间的沟通和交流。然而&#xff0c;随着客户需求的不断增长和高峰时段的到来&#xff0c;传统的呼叫中心运营方式往往…

C语言:有两个磁盘文件A和B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件C中

int main() {int i, j 0;char arr_pfa[100], arr_pfb[100];FILE* pfa fopen("A.txt", "r");//自己事先创建 我这里A存放的是helloif (pfa NULL){perror("error:");return 1;}fgets(arr_pfa, 100, pfa);fclose(pfa);FILE* pfb fopen("B.…

【数据结构】神奇的二叉树

文章目录 前言1. 树形结构1.1 什么是树1.2 名词概念1.3 树的表现形式 2. 二叉树2.1 概念2.2 两种特殊的二叉树2.3 二叉树的性质 3. 二叉树的存储结构3.1 顺序存储3.2 链式存储 4. 二叉树的遍历4.1 前序遍历4.2 中序遍历4.3 后序遍历4.4 层序遍历 5. 遍历的代码实现5.1 递归实现…

PTT票据传递攻击

一. PTT票据传递攻击原理 1.PTT介绍 PTT(Pass The Ticket)&#xff0c;中文叫票据传递攻击&#xff0c;PTT 攻击只能用于kerberos认证中,NTLM认证中没有&#xff0c; PTT是通过票据进行认证的。 进行票据传递&#xff0c;不需要提权&#xff0c;域用户或者system用户就可以 …

深入探讨Java泛型:详解Java泛型的工作原理,擦除,包括通配符以及在编程实践中的使用和注意事项

1. Java泛型简介 1. 泛型的主要目的 泛型主要有两个目的: 提高类型安全:在编译时进行严格的类型检查。有了泛型,可以确保在编译时而不是在运行时发现类型问题,从而降低了类类型转换错误的可能性。 消除代码冗余:避免在代码中使用过多的类型转换,提高代码的可读性和可…

HTTP 和高级编程

目录 一.HTTP 简介 HTTP 工作原理 HTTP 请求 HTTP 响应 HTTP 的常见应用 HTTP 的优点 HTTP 的缺点 二.使用 CHtmlView 类创建 Web 视图 创建 CHtmlView 控件 CHtmlView 类成员函数 CHtmlView 类事件 使用 CHtmlView 类创建 Web 浏览器 三.Web 浏览器应用程序示例 一…

【图书推荐】《Vue.js 3.x+Element Plus从入门到精通(视频教学版)》

本书用处 内容简介 本书通过对Vue.js&#xff08;简称Vue&#xff09;的示例和综合案例的介绍与演练&#xff0c;使读者快速掌握Vue.js 3.x框架的用法&#xff0c;提高Web前端的实战开发能力。本书配套示例源码、PPT课件、教学大纲、教案、同步教学视频、习题及答案、其他资源…

HTML+CSS 响应式导航栏

效果演示 Code <div class="navbar"><input type="checkbox"><span></span><span></span><ul><li><a href="#">点赞</a></li><li><a href="#">关注&…

模拟器玩游戏

IOS系统 【PPSSPP与Retroarch 模拟器上架苹果商店&#xff0c;教你如何玩转复古游戏模拟器】 安卓

SpringCloud+Python 混合微服务,如何打造AI分布式业务应用的技术底层?

尼恩&#xff1a;LLM大模型学习圣经PDF的起源 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;经常性的指导小伙伴们改造简历。 经过尼恩的改造之后&#xff0c;很多小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试机会&#x…

【数据结构】数据结构中的隐藏玩法——栈与队列

前言&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累。我…

依赖管理与Springboot Starters

依赖管理与Spring Boot Starters 在现代软件开发过程中&#xff0c;依赖管理是一项至关重要的任务。随着应用程序规模的扩大&#xff0c;引入的依赖项数量也会增加&#xff0c;使得版本冲突和类路径问题成为常见的挑战。为了应对这些挑战&#xff0c;Spring Boot提供了一套简化…

【OpenCV 基础知识 11】计算通道像素值和

cvSplit()函数将复制src的各个通道到图像dst0&#xff0c;dst1&#xff0c;dst2和dst3中。如果源图像少于4个通道的情况下&#xff0c;那么传递给cvSplit()的不必要的目标参数可设置为NULL program cv_Sum;{$APPTYPE CONSOLE} {$R *.res}usesSystem.SysUtils,ocv.highgui_c,oc…

前端基于word模板导出word文档

项目环境 vue2 js vue-cli等 依赖包都可以在npm官网找到对应文档 npm官网(英文) 1、依赖 安装依赖 docxtemplater npm i docxtemplaterfile-saver npm i file-saverjszip-utils npm i jszip-utilsjszip npm i jszip在对应页面或模块中引入依赖 import Docxtemplater …