?使用過C語言的童鞋都知道,使用printf可以在終端(控制臺或者串口等輸出設備)輸出信息,這為我們平時調(diào)試程序提供了便利,只是我們通常的打印用法,僅僅是 printf("Hello World !\r\n"); 毫無生氣,控制臺也僅僅是輸出,白底黑字的 Hello World !
今天我將給大家介紹一種帶顏色輸出的printf用法,從此你將告訴枯燥單調(diào)的輸出,你的日志也可以變成屬于你自己的“藝術品”!話不多說,先來張圖感受下 !!! 注意 72 行的輸出其實是間隙閃爍的哦,只不過截圖了感受不出來。
以下是正文部分,通過本文的閱讀,你將了解到以下內(nèi)容:
- printf帶顏色控制的打印輸出
- 日志分級別打印的實踐
printf帶顏色控制的打印輸出
printf帶顏色輸出,首先需要了解下控制臺輸出的屬性設置原理:通過用一串轉(zhuǎn)義序列將輸出的控制信息嵌入到printf語句中。
【轉(zhuǎn)義序列】是以控制字符'ESC'開頭。該字符的ASCII碼十進制表示為27,十六進制表示為0x1B,八進制表示為033。多數(shù)轉(zhuǎn)義序列超過兩個字符,故通常以'ESC'和左括號'['開頭。該起始序列稱為控制序列引導符(CSI,Control Sequence Intro),通常由'\033['或'\e['代替。通過轉(zhuǎn)義序列設置終端顯示屬性時,可采用以下格式:
\033[ Param {;Param;...}m 或 \e[ Param {;Param;...}m
其中,'\033['或'\e['引導轉(zhuǎn)義序列,'m'表示設置屬性并結束轉(zhuǎn)義序列。Param為屬性值,{...}表示可選(多個參數(shù)之間用分號隔開,與順序無關)。
【顏色】是通過添加專用序列來選擇的 -- 基本上是夾在 "\e["和 "m" 之間數(shù)字值。如果指定一個以上的數(shù)字代碼,則用分號將它們分開。例如"\e[31;40m";第一個數(shù)字(31)為前景顏色(紅色);第二個數(shù)字為(40)背景顏色(黑色); "\e[0m" 表示關閉設置屬性。
【顯示】:0(默認)、1(粗體/高亮)、22(非粗體)、4(單條下劃線)、24(無下劃線)、5(閃爍)、25(無閃爍)、7(反顯、翻轉(zhuǎn)前景色和背景色)、27(無反顯)
【顏色值】:0(黑)、1(紅)、2(綠)、 3(黃)、4(藍)、5(紫)、6(深綠)、7(白);顏色分為背景色和字體色,30~39(30+顏色值)用來設置字體色(前景色),40~49(40+顏色值)設置背景(背景色):如31表示前景色為紅色,41表示背景色為紅色。
好了,基本知識就介紹到,以下是前面圖片對應的示例代碼。
#include
/*
顯示:0(默認)、1(粗體/高亮)、22(非粗體)、4(單條下劃線)、24(無下劃線)、5(閃爍)、25(無閃爍)、7(反顯、翻轉(zhuǎn)前景色和背景色)、27(無反顯)
顏色值:0(黑)、1(紅)、2(綠)、 3(黃)、4(藍)、5(紫)、6(深綠)、7(白)
顏色分為背景色和字體色,30~39(30+顏色值)用來設置字體色(前景色),40~49(40+顏色值)設置背景(背景色):如31表示前景色為紅色,41表示背景色為紅色。
*/
#define COLOR_NONE "\033[0;m"
#define RED "\033[0;31m"
#define LIGHT_RED "\033[1;31m" //紅色高亮
#define LIGHT_RED_INV "\033[5;7;31m" //紅色高亮,并反白顯示,字體閃爍
#define GREEN "\033[0;32m"
#define LIGHT_GREEN "\033[1;32m"
#define BLUE "\033[0;34m"
#define LIGHT_BLUE "\033[1;34m" //藍色高亮
#define DARY_GRAY "\033[1;30m"
#define CYAN "\033[0;36m"
#define LIGHT_CYAN "\033[1;36m"
#define PURPLE "\033[0;35m"
#define LIGHT_PURPLE "\033[1;35m"
#define YELLOW "\033[0;33m"
#define LIGHT_YELLOW "\033[1;33m" //黃色高亮
#define WHITE "\033[0;37m"
#define LIGHT_WHITE "\033[1;37m" //白色高亮
/*
日志級別定義,數(shù)值越小,級別越高
*/
#define LOGGER_FATAL_LEVEL 1 //致命錯誤,不可恢復
#define LOGGER_ERROR_LEVEL 2 //一般錯誤,可恢復
#define LOGGER_WARN_LEVEL 3 //警告
#define LOGGER_INFO_LEVEL 4 //信息
#define LOGGER_DEBUG_LEVEL 5 //調(diào)試
/*
當前日志級別配置
*/
#define LOGGER_CFG_LEVEL LOGGER_DEBUG_LEVEL
/*
根據(jù)配置的日志級別輸出日志
*/
#define logger_level_printf(level, fmt, arg...)\
do {\
if (level <= LOGGER_CFG_LEVEL) {\
printf("[%s,%d] "fmt, __FILE__, __LINE__, ##arg);\
}\
} while(0)
#define logger_fatal(fmt, arg...) logger_level_printf(LOGGER_FATAL_LEVEL, LIGHT_RED_INV fmt COLOR_NONE, ##arg)
#define logger_error(fmt, arg...) logger_level_printf(LOGGER_ERROR_LEVEL, LIGHT_RED fmt COLOR_NONE, ##arg)
#define logger_warn(fmt, arg...) logger_level_printf(LOGGER_WARN_LEVEL, LIGHT_YELLOW fmt COLOR_NONE, ##arg)
#define logger_info(fmt, arg...) logger_level_printf(LOGGER_INFO_LEVEL, LIGHT_BLUE fmt COLOR_NONE, ##arg)
#define logger_debug(fmt, arg...) logger_level_printf(LOGGER_DEBUG_LEVEL, LIGHT_WHITE fmt COLOR_NONE, ##arg)
int main(int argc, const char *argv[])
{
/* 普通的printf輸出 */
printf("This is my function called %s() ...\n", __func__);
/* 測試不同的日志輸出 */
logger_fatal("This fatal log ...\r\n");
logger_error("This error log ...\r\n");
logger_warn("This warn log ...\r\n");
logger_info("This info log ...\r\n");
logger_debug("This debug log ...\r\n");
return 0;
}
日志分級別打印的實踐
示例代碼中將日志分為五個級別,從對運行的影響的重要性,從高到低分別是: 致命錯誤、普通錯誤、警告、信息、調(diào)試。
致命錯誤fatal級別的日志使用 “高亮紅色輸出,并且反色輸出,同時字體間隙閃爍”;
普通錯誤error級別的日志使用 “高亮紅色輸出”;
警告warn級別的日志使用 “高亮黃色輸出”;
信息info級別的日志使用 “高亮藍色輸出”;
調(diào)試debug級別的日志使用 “高亮白色輸出”;
另外,有個宏LOGGER_CFG_LEVEL 可以配置當前的日志級別,此項配置的含義是,當需要輸出的日志級別比配置的日志級別高時,該日志就會被最終輸出,否則該日志則會被拋棄。【數(shù)值越小,表示日志級別越高】
示例代碼中配置的是debug級別,所以所有級別的日志都會被輸出。我們試下修改日志級別配置,配置成warn級別:
/*
當前日志級別配置
*/
#define LOGGER_CFG_LEVEL LOGGER_WARN_LEVEL
編譯后測試下
這基本就達到了我們需要控制日志輸出的需求。
好了,關于printf帶顏色輸出和日志分級別輸出的內(nèi)容就介紹到這里,如果你覺得有幫助,可以試著應用在你的工程中,讓你的日志輸出高效起來吧 !!!
?審核編輯:湯梓紅
-
C語言
+關注
關注
180文章
7604瀏覽量
136713 -
RT-Thread
+關注
關注
31文章
1285瀏覽量
40094 -
Printf
+關注
關注
0文章
83瀏覽量
13651
發(fā)布評論請先 登錄
相關推薦
評論