接著上一篇文章《由字節(jié)對(duì)齊引發(fā)的一場(chǎng)“血案“ 》
在平常的調(diào)試中,printf字體格式與顏色都是默認(rèn)一致的。
如果可以根據(jù)log信息的重要程度,配以不同的顏色與格式,可以很方便的查找到要點(diǎn)。
1、printf字體顯示語(yǔ)法說明
printf(“033[顯示方式;字體顏色;背景顏色m?字符串?033[0m”?);
語(yǔ)法說明:
第一個(gè)**33[**表示轉(zhuǎn)義序列的開始,設(shè)置隨后的字體格式轉(zhuǎn)義序列是以ESC開頭,用33完成相同的工作(ESC 的 ASCII 碼用十進(jìn)制表示就是27,=用八進(jìn)制表示的33)。
- 顯示方式:0:默認(rèn)值 ?1:高亮 、22:非粗體、4:下劃線、24:非下劃線、5:閃爍、25:非閃爍、7:反顯、27:非反顯字體顏色30: 黑 ? 31: 紅 32: 綠 33: 黃 34: 藍(lán) 35: 紫 36: 深綠 37: 白色背景顏色40: 黑 41: 紅 42: 綠 43: 黃 44: 藍(lán) 45: 紫 46: 深綠 47: 白色紅色 ?'m':表示轉(zhuǎn)義序列的結(jié)束結(jié)尾處的**33[0m**是恢復(fù)默認(rèn)值。
其他ANSI控制碼:
????/033[0m?關(guān)閉所有屬性
????/033[1m?設(shè)置高亮度
????/033[4m?下劃線
????/033[5m?閃爍
????/033[7m?反顯
????/033[8m?消隱
????/033[30m?--?/033[37m?設(shè)置前景色
????/033[40m?--?/033[47m?設(shè)置背景色
????/033[nA?光標(biāo)上移n行
????/033[nB?光標(biāo)下移n行
????/033[nC?光標(biāo)右移n行
????/033[nD?光標(biāo)左移n行
????/033[y;xH設(shè)置光標(biāo)位置
????/033[2J?清屏
????/033[K?清除從光標(biāo)到行尾的內(nèi)容
????/033[s?保存光標(biāo)位置
????/033[u?恢復(fù)光標(biāo)位置
????/033[?25l?隱藏光標(biāo)
????/033[?25h?顯示光標(biāo)
注意:
其中 顯示方式;字體顏色;背景顏色 可以任意組合,";"隔開即可。
使用 ANSI 轉(zhuǎn)義碼來(lái)設(shè)置文本樣式和顏色可能會(huì)因?yàn)椴煌慕K端軟件和操作系統(tǒng)而產(chǎn)生不同的效果。
同時(shí),這種方式也只適用于在終端上輸出,如果需要在 GUI 程序中設(shè)置文本顏色等效果,則需要使用相應(yīng)的 GUI 庫(kù)提供的接口。
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[' 是轉(zhuǎn)義序列的開始,'m' 是轉(zhuǎn)義序列的結(jié)束,'33[0m' 表示將屬性重置為默認(rèn)值。
運(yùn)行結(jié)果:
方式
?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");
色譜
測(cè)試代碼[僅打印字體顏色]
????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"???????//清除?
將系統(tǒng)提供的printf函數(shù)做一個(gè)封裝:
#define?myprintf(color,?format,?args...)????????
????do{?????????????
????????????printf(color);?????????????
????????????printf(format,?##args);??????????
????????????printf(PF_CLR);?????????????
????}while(0)?
比如我們要打印字符串,顯示為高亮黃色
myprintf(HL_YEL,"%sn","yikoulinux");
4. ?美化程序的打印log
假設(shè)我們有如下格式的通信信令:
調(diào)試通信協(xié)議,
我們經(jīng)常需要將通信的信令以16進(jìn)制格式全部打印出來(lái),
這些數(shù)據(jù)看起來(lái)非常不直觀,
為方便查看log,將幾個(gè)最重要字段顯示出來(lái),
比如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');?
}?
將我們的測(cè)試針數(shù)據(jù),放進(jìn)去測(cè)試一下
?UCHAR?frm[]={0x12,0x34,0x56,0x00,0x07,0x01,0x02,0x03,0x04,0x05,0x06,0x07};
?
dump_frm("frm<<<",frm,sizeof(frm));
執(zhí)行結(jié)果:
可以看到,這種幀格式,看起來(lái)會(huì)更加直觀,
5、完整代碼
國(guó)際慣例,貼上完整代碼,
需要的老鐵,直接拷貝帶你們的項(xiàng)目里吧
?#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;
}