加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入
  • 正文
    • 1、printf字体显示语法说明
    • 2、举例
    • 3、给打印信息封装
    • 4.  美化程序的打印log
    • 5、完整代码
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

如何让你的C程序打印的log多一点色彩?(超级实用)

07/29 11:20
2889
阅读需 21 分钟
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

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

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

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

1、printf字体显示语法说明

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

语法说明:

第一个**33[**表示转义序列的开始,设置随后的字体格式转义序列是以ESC开头,用33完成相同的工作(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':表示转义序列的结束结尾处的**33[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("33[1;31mThis text is in red and bold.33[0mn");
 printf("33[0;31mThis text is in red and not bold.33[0mn");

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

运行结果:

方式

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

色谱

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

    printf("33[30m****一口Linux*****【30】33[0mrn");
    printf("33[31m****一口Linux*****【31】33[0mrn");
    printf("33[32m****一口Linux*****【32】33[0mrn");
    printf("33[33m****一口Linux*****【33】33[0mrn");
    printf("33[34m****一口Linux*****【34】33[0mrn");
    printf("33[35m****一口Linux*****【35】33[0mrn"); 
    printf("33[36m****一口Linux*****【36】33[0mrn");
    printf("33[37m****一口Linux*****【37】33[0mrn"); 

    printf("33[40m****一口Linux*****【40】33[0mrn");
    printf("33[41m****一口Linux*****【41】33[0mrn");
    printf("33[42m****一口Linux*****【42】33[0mrn");
    printf("33[43m****一口Linux*****【43】33[0mrn");
    printf("33[44m****一口Linux*****【44】33[0mrn");
    printf("33[45m****一口Linux*****【45】33[0mrn"); 
    printf("33[46m****一口Linux*****【46】33[0mrn");
    printf("33[47m****一口Linux*****【47】33[0mrn"); 

3、给打印信息封装

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

#define HL_TWK_RED_YEL  "33[1m33[5;31;43m" //闪烁高亮红字黄底
#define HL_RED_WRT      "33[1;31;47m"   //高亮红色白底

#define HL_RED          "33[1;31m"    //高亮红色
#define HL_GRN          "33[1;32m"    //高亮绿色
#define HL_YEL          "33[1;33m"    //高亮黄色
#define HL_DGRN          "33[1;36m"    //高亮深绿

#define PF_CLR  "33[0m"       //清除 

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

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

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

myprintf(HL_YEL,"%sn","yikoulinux");

4.  美化程序的打印log

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

调试通信协议

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

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

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

比如msgType、len

  
void dump_frm(char *title,UINT8 *data,int len)
{
 int i=0;
  
 myprintf(HL_YEL,"%sn",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  "33[1m33[5;31;43m" //闪烁高亮红字黄底
#define HL_RED_WRT      "33[1;31;47m"   //高亮红色白底

#define HL_RED          "33[1;31m"    //高亮红色
#define HL_GRN          "33[1;32m"    //高亮绿色
#define HL_YEL          "33[1;33m"    //高亮黄色
#define HL_DGRN          "33[1;36m"    //高亮深绿

#define PF_CLR  "33[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,"%sn",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("33[1;31mThis text is in red and bold.33[0mn");
 printf("33[0;31mThis text is in red and not bold.33[0mn");

 
 printf("33[0;36m****一口Linux*****【0;36m】33[0mrn");
 printf("33[1;36m****一口Linux*****【1;36m】33[0mrn");
 printf("33[4;36m****一口Linux*****【4;36m】33[0mrn");
 printf("33[5;36m****一口Linux*****【5;36m】33[0mrn");
 printf("33[7;36m****一口Linux*****【7;36m】33[0mrn");
 printf("33[8;36m****一口Linux*****【8;36m】33[0mrn");
 printf("33[22;36m****一口Linux*****【22;36m】33[0mrn");
 printf("33[24;36m****一口Linux*****【24;36m】33[0mrn");
 printf("33[25;36m****一口Linux*****【25;36m】33[0mrn");
 printf("33[27;36m****一口Linux*****【27;36m】33[0mrn");
 
    printf("33[30m****一口Linux*****【30】33[0mrn");
    printf("33[31m****一口Linux*****【31】33[0mrn");
    printf("33[32m****一口Linux*****【32】33[0mrn");
    printf("33[33m****一口Linux*****【33】33[0mrn");
    printf("33[34m****一口Linux*****【34】33[0mrn");
    printf("33[35m****一口Linux*****【35】33[0mrn"); 
    printf("33[36m****一口Linux*****【36】33[0mrn");
    printf("33[37m****一口Linux*****【37】33[0mrn"); 

    printf("33[40m****一口Linux*****【40】33[0mrn");
    printf("33[41m****一口Linux*****【41】33[0mrn");
    printf("33[42m****一口Linux*****【42】33[0mrn");
    printf("33[43m****一口Linux*****【43】33[0mrn");
    printf("33[44m****一口Linux*****【44】33[0mrn");
    printf("33[45m****一口Linux*****【45】33[0mrn"); 
    printf("33[46m****一口Linux*****【46】33[0mrn");
    printf("33[47m****一口Linux*****【47】33[0mrn"); 
 
 #endif
    return 0;
}

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
SN74LVC1G14DBVT 1 Texas Instruments Single 1.65-V to 5.5-V inverter with Schmitt-Trigger inputs 5-SOT-23 -40 to 125

ECAD模型

下载ECAD模型
$0.93 查看

相关推荐

电子产业图谱

公众号『一口Linux』号主彭老师,拥有15年嵌入式开发经验和培训经验。曾任职ZTE,某研究所,华清远见教学总监。拥有多篇网络协议相关专利和软件著作。精通计算机网络、Linux系统编程、ARM、Linux驱动、龙芯、物联网。原创内容基本从实际项目出发,保持原理+实践风格,适合Linux驱动新手入门和技术进阶。