接着上一篇文章《由字节对齐引发的一场“血案“

在平常的调试中,printf字体格式与颜色都是默认一致的。

如果可以根据log信息的重要程度,配以不同的颜色与格式,可以很方便的查找到要点。

1、printf字体显示语法说明

printf(“\033[显示方式;字体颜色;背景颜色m 字符串 \033[0m” );

语法说明:

  • 第一个\033[表示转义序列的开始,设置随后的字体格式

    转义序列是以 ESC 开头,用 \033 完成相同的工作(ESC 的 ASCII 码用十进制表示就是 27= 用八进制表示的 33)。

  • 显示方式:

    0:默认值 1:高亮 、22:非粗体、4:下划线、24:非下划线、5:闪烁、25:非闪烁、7:反显、27:非反显

  • 字体颜色

    30: 黑 31: 红 32: 绿 33: 黄 34: 蓝 35: 紫 36: 深绿 37: 白色

  • 背景颜色

    40: 黑 41: 红 42: 绿 43: 黄 44: 蓝 45: 紫 46: 深绿 47: 白色

  • 红色 'm':表示转义序列的结束

  • 结尾处的\033[0m是恢复默认值。

其他ANSI控制码:

    /033[0m 关闭所有属性
/033[1m 设置高亮度
/033[4m 下划线
/033[5m 闪烁
/033[7m 反显
/033[8m 消隐
/033[30m -- /033[37m 设置前景色
/033[40m -- /033[47m 设置背景色
/033[nA 光标上移n行
/033[nB 光标下移n行
/033[nC 光标右移n行
/033[nD 光标左移n行
/033[y;xH设置光标位置
/033[2J 清屏
/033[K 清除从光标到行尾的内容
/033[s 保存光标位置
/033[u 恢复光标位置
/033[?25l 隐藏光标
/033[?25h 显示光标

注意:

其中 显示方式;字体颜色;背景颜色 可以任意组合,";"隔开即可。

使用 ANSI 转义码来设置文本样式和颜色可能会因为不同的终端软件和操作系统而产生不同的效果。

同时,这种方式也只适用于在终端上输出,如果需要在 GUI 程序中设置文本颜色等效果,则需要使用相应的 GUI 库提供的接口。

2、举例

	printf("\033[1;31mThis text is in red and bold.\033[0m\n");
printf("\033[0;31mThis text is in red and not bold.\033[0m\n");

其中,'1' 表示加粗或高亮,'31' 表示前景色为红色,'\033[' 是转义序列的开始,'m' 是转义序列的结束,'\033[0m' 表示将属性重置为默认值。

运行结果:

方式

	printf("\033[0;36m****一口Linux*****【0;36m】\033[0m\r\n");
printf("\033[1;36m****一口Linux*****【1;36m】\033[0m\r\n");
printf("\033[4;36m****一口Linux*****【4;36m】\033[0m\r\n");
printf("\033[5;36m****一口Linux*****【5;36m】\033[0m\r\n");
printf("\033[7;36m****一口Linux*****【7;36m】\033[0m\r\n");
printf("\033[8;36m****一口Linux*****【8;36m】\033[0m\r\n");
printf("\033[22;36m****一口Linux*****【22;36m】\033[0m\r\n");
printf("\033[24;36m****一口Linux*****【24;36m】\033[0m\r\n");
printf("\033[25;36m****一口Linux*****【25;36m】\033[0m\r\n");
printf("\033[27;36m****一口Linux*****【27;36m】\033[0m\r\n");

色谱

测试代码[仅打印字体颜色]

    printf("\033[30m****一口Linux*****【30】\033[0m\r\n");
printf("\033[31m****一口Linux*****【31】\033[0m\r\n");
printf("\033[32m****一口Linux*****【32】\033[0m\r\n");
printf("\033[33m****一口Linux*****【33】\033[0m\r\n");
printf("\033[34m****一口Linux*****【34】\033[0m\r\n");
printf("\033[35m****一口Linux*****【35】\033[0m\r\n");
printf("\033[36m****一口Linux*****【36】\033[0m\r\n");
printf("\033[37m****一口Linux*****【37】\033[0m\r\n"); printf("\033[40m****一口Linux*****【40】\033[0m\r\n");
printf("\033[41m****一口Linux*****【41】\033[0m\r\n");
printf("\033[42m****一口Linux*****【42】\033[0m\r\n");
printf("\033[43m****一口Linux*****【43】\033[0m\r\n");
printf("\033[44m****一口Linux*****【44】\033[0m\r\n");
printf("\033[45m****一口Linux*****【45】\033[0m\r\n");
printf("\033[46m****一口Linux*****【46】\033[0m\r\n");
printf("\033[47m****一口Linux*****【47】\033[0m\r\n");

3、给打印信息封装

为方便打印字符串为不同颜色,我们可以将一些常用的颜色定义成宏

#define HL_TWK_RED_YEL  "\033[1m\033[5;31;43m"	//闪烁高亮红字黄底
#define HL_RED_WRT "\033[1;31;47m" //高亮红色白底 #define HL_RED "\033[1;31m" //高亮红色
#define HL_GRN "\033[1;32m" //高亮绿色
#define HL_YEL "\033[1;33m" //高亮黄色
#define HL_DGRN "\033[1;36m" //高亮深绿 #define PF_CLR "\033[0m" //清除

将系统提供的printf函数做一个封装:

#define myprintf(color, format, args...)        \
do{ \
printf(color); \
printf(format, ##args); \
printf(PF_CLR); \
}while(0)

比如我们要打印字符串,显示为高亮黄色

myprintf(HL_YEL,"%s\n","yikoulinux");

4. 美化程序的打印log

假设我们有如下格式的通信信令:

调试通信协议,

我们经常需要将通信的信令以16进制格式全部打印出来,

这些数据看起来非常不直观,

为方便查看log,将几个最重要字段显示出来,

比如msgType、len


void dump_frm(char *title,UINT8 *data,int len)
{
int i=0; myprintf(HL_YEL,"%s\n",title);
for(i=0;i<len;i++)
{
if(i==0){
myprintf(HL_RED,"%02x ",data[i]);
}else if(i==3 || i==4){
myprintf(HL_DGRN,"%02x ",data[i]);
}
else{
myprintf(HL_GRN,"%02x ",data[i]);
}
}
putchar('\n');
}

将我们的测试针数据,放进去测试一下

	UCHAR frm[]={0x12,0x34,0x56,0x00,0x07,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

dump_frm("frm<<<",frm,sizeof(frm));

执行结果:



可以看到,这种帧格式,看起来会更加直观,

5、完整代码

国际惯例,贴上完整代码,

需要的老铁,直接拷贝带你们的项目里吧

 #include <stdio.h>
#include <string.h> typedef unsigned char UCHAR;
typedef unsigned char UINT8;
typedef unsigned short UINT16;
#pragma pack(1)
typedef struct protocol_msg_align{
UINT8 msgType;
UINT8 data1;
UINT8 data2;
UINT16 len;
char data[100];
}PRO_MSG_ALIGN;
#pragma #define HL_TWK_RED_YEL "\033[1m\033[5;31;43m" //闪烁高亮红字黄底
#define HL_RED_WRT "\033[1;31;47m" //高亮红色白底 #define HL_RED "\033[1;31m" //高亮红色
#define HL_GRN "\033[1;32m" //高亮绿色
#define HL_YEL "\033[1;33m" //高亮黄色
#define HL_DGRN "\033[1;36m" //高亮深绿 #define PF_CLR "\033[0m" //清除 #define myprintf(color, format, args...) \
do{ \
printf(color); \
printf(format, ##args); \
printf(PF_CLR); \
}while(0) void dump_frm(char *title,UINT8 *data,int len)
{
int i=0; myprintf(HL_YEL,"%s\n",title);
for(i=0;i<len;i++)
{
if(i==0){
myprintf(HL_RED,"%02x ",data[i]);
}else if(i==3 || i==4){
myprintf(HL_DGRN,"%02x ",data[i]);
}
else{
myprintf(HL_GRN,"%02x ",data[i]);
}
}
putchar('\n');
} int main(int args, char *argv[])
{
UCHAR frm[]={0x12,0x34,0x56,0x00,0x07,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
dump_frm("frm<<<",frm,sizeof(frm));
#if 0
printf("\033[1;31mThis text is in red and bold.\033[0m\n");
printf("\033[0;31mThis text is in red and not bold.\033[0m\n"); printf("\033[0;36m****一口Linux*****【0;36m】\033[0m\r\n");
printf("\033[1;36m****一口Linux*****【1;36m】\033[0m\r\n");
printf("\033[4;36m****一口Linux*****【4;36m】\033[0m\r\n");
printf("\033[5;36m****一口Linux*****【5;36m】\033[0m\r\n");
printf("\033[7;36m****一口Linux*****【7;36m】\033[0m\r\n");
printf("\033[8;36m****一口Linux*****【8;36m】\033[0m\r\n");
printf("\033[22;36m****一口Linux*****【22;36m】\033[0m\r\n");
printf("\033[24;36m****一口Linux*****【24;36m】\033[0m\r\n");
printf("\033[25;36m****一口Linux*****【25;36m】\033[0m\r\n");
printf("\033[27;36m****一口Linux*****【27;36m】\033[0m\r\n"); printf("\033[30m****一口Linux*****【30】\033[0m\r\n");
printf("\033[31m****一口Linux*****【31】\033[0m\r\n");
printf("\033[32m****一口Linux*****【32】\033[0m\r\n");
printf("\033[33m****一口Linux*****【33】\033[0m\r\n");
printf("\033[34m****一口Linux*****【34】\033[0m\r\n");
printf("\033[35m****一口Linux*****【35】\033[0m\r\n");
printf("\033[36m****一口Linux*****【36】\033[0m\r\n");
printf("\033[37m****一口Linux*****【37】\033[0m\r\n"); printf("\033[40m****一口Linux*****【40】\033[0m\r\n");
printf("\033[41m****一口Linux*****【41】\033[0m\r\n");
printf("\033[42m****一口Linux*****【42】\033[0m\r\n");
printf("\033[43m****一口Linux*****【43】\033[0m\r\n");
printf("\033[44m****一口Linux*****【44】\033[0m\r\n");
printf("\033[45m****一口Linux*****【45】\033[0m\r\n");
printf("\033[46m****一口Linux*****【46】\033[0m\r\n");
printf("\033[47m****一口Linux*****【47】\033[0m\r\n"); #endif
return 0;
}

如何让你的C语言程序打印的log多一点色彩?(超级实用)的更多相关文章

  1. 微信小程序打印json log

    微信小程序中如果 res.data数据是一个json格式数据.console.log("===data===" + res.data);//如果这样打印出了是只会打印一个对象名称, ...

  2. IOS开发--C语言入门--如何结合Terminal和Vim开发C语言程序

    一直以来都想着挤出时间,记录开发之路的点点滴滴(现在记录已成回忆),和大家一起分享,开发人员总是在沟通和相互学习中提高自身的能力.路过的大神也好初学者也罢,若发现文章中又观点不对的,还望大家指出. 现 ...

  3. 如何把一个c语言程序做成windows服务开机自启动

    原文:如何把一个c语言程序做成windows服务开机自启动 目前写的程序是一个用c语言实现socket侦听的,那么如何把这个程序做成开机自启动呢? 我们是通过vs6.0,编译后生成了.exe文件,然后 ...

  4. 在android系统上写C语言程序--开机启动该程序不进入安卓系统

    今天要写的这篇博文意义重大,也是网上很少有的,这是在我工作中学会的一项技术,当然,它也是由简单的问题组合而来的.如何在安卓中写C语言程序,调试安卓驱动,测试程序的的一项重要技能,下面我就不说废话了,直 ...

  5. Android For JNI(一)——JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序,使用C启动JAVA程序

    Android For JNI(一)--JNI的概念以及C语言开发工具dev-c++,编写你的第一个C语言程序 当你的Android之旅一步步的深入的时候,你其实会发现,很多东西都必须去和framew ...

  6. 一个简单的C语言程序(详解)

    C Primer Plus之一个简单的C语言程序(详解) #include <stdio.h> int main(void) //一个简单的 C程序 { int num; //定义一个名为 ...

  7. Objective-C 学习笔记(一) 语言程序结构

    Objective-C语言程序结构 “Hello World”简单示例 #import <Foundation/Foundation.h> //预处理命令,它告诉Objective-C语言 ...

  8. 100个经典C语言程序(益智类)

    100个经典C语言程序(益智类) [1.绘制余弦曲线] 在屏幕上用“*”显示0~360度的余弦函数cos(x)曲线 [问题分析与算法设计] 利用cos(x)的左右对称性,将屏幕的行方向定义为x,列方向 ...

  9. C语言编程入门之--第三章编写第一个C语言程序

    第三章 编写第一个C语言程序 导读:一般学一门计算机语言的第一堂上机课(“上机”顾名思义,上了计算机),就是往屏幕输出“hello world”,本章也不例外. 1.1 Hello,World! 这一 ...

  10. Linux编译C语言程序

    1.首先安装gcc包,运行C++程序,安装gcc-c++ 包 如果没有安装的自行进行安装 2.编辑C语言程序, 打印乘法口诀表 [root@Db1 c]# vim chengfa.c 在编辑界面中,输 ...

随机推荐

  1. CodeServer 不能粘贴

    CodeServer 在没有SSL证书时, 由一浏览器的限制, 默认是不能粘贴的. 在局域网中, 如果不考虑安全性的话, 可以考虑直接把加密关掉, 就能复制粘贴了. 配置文件如下: cert: Tru ...

  2. IPTABLES管理

    iptables 是 Linux 管理员用来设置 IPv4 数据包过滤条件和 NAT 的命令行工具.iptables 工具运行在用户态,主要是设置各种规则.而 netfilter 则运行在内核态,执行 ...

  3. 一款利用人工智能将自然语言查询转换为 SQL 代码的互译工具 - SQL Translator

    前言 对于后端程序员来说,编写SQL代码是日常工作中不可或缺的一部分.然而,随着数据复杂性的增加,如何高效.准确地编写SQL查询成为了新的挑战.幸运的是,SQL Translator的出现为后端程序员 ...

  4. Apline部署K3s的Agent

    之前我们在Ubuntu上部署了K3s的Server节点(传送门),这次我们加入两台K3s的Agent节点搭建一个K3s的3节点工作环境. 需要准备好网络环境,确保三台VM之间是可以ping通的,设置好 ...

  5. 一个用来画拉氏图的简单Python脚本

    技术背景 关于拉氏图的更多介绍,可以参考下这篇博客,这里简单引述一部分内容: Ramachandran plot(拉氏图)是由G. N. Ramachandran等人于1963年开发的,用来描述蛋白质 ...

  6. Windows批处理文件(.bat和.cmd)

    cmd文件和bat文件的区别 从文件描述中的区别是,cmd文件叫做:Windows命令脚本,bat文件叫:批处理文件,两者都可以使用任意一款文本编辑器进行创建.编辑和修改,只是在cmd中支持的命令要多 ...

  7. PHP7新特性之类型声明

    今天我在这里总结下PHP7主要的新特性. 1.类型声明 做过php开发的小伙伴们都知道,php7以前的版本变量是不需要声明类型的,函数返回值也是不需要声明类型的,总之,在我们的脑海中就没有这么回事.可 ...

  8. [oeasy]python0083_十进制数如何存入计算机_八卦纪事_BCD编码_Binary_Coded_Decimal

    编码进化 回忆上次内容 上次 研究了 视频终端的 演化 从VT05 到 VT100 从 黑底绿字 到 RGB 24位真彩色 形成了 VT100选项 从而 将颜色 数字化 了 生活中我们更常用 10个数 ...

  9. SQL Server 图解备份(完全备份、差异备份、增量备份)和还原

    常用的数据备份方式有完全备份.差异备份以及增量备份,那么这三种备份方式有什么区别,在具体应用中又该如何选择呢? 1.三种备份方式 完全备份(Full Backup):备份全部选中的文件夹,并不依赖文件 ...

  10. C#:SqlSugar中时间戳(TimeStamp)的使用

    1.数据库建表 CREATE TABLE dbo.Test ( tId INT IDENTITY NOT NULL , tName NVARCHAR (20) NOT NULL , tSalary D ...