我們在linux下安裝軟體時經常會看到一個進度條,就像下面這樣:
[########################################################][100%][/]
那麼,我們有沒有辦法實現一個簡單的進度條呢。linux下的進度條配色太單調,我們有沒有辦法實現一個彩色的進度條呢。想想都有趣,下面就讓我們來操作一下吧。
其實,幾行代碼就可以類比出來一個簡單的彩色進度條,就像這樣:
#include<stdio.h>#include<string.h>#include<unistd.h>int main() { int i = 0; int j = 0; char bar[102]; //建立color數組存放顏色 int color[] = { 1,2,3,4,5,6,7 }; const char* status = "|/-\\"; memset(bar, 0, sizeof(bar)); while (i <= 100) { printf("\033[3%dm[%-100s]\033[0m\033[33m[%d%%]\033[0m[%c]\r", color[j], bar, i, status[i % 4]); //重新整理緩衝區的內容 fflush(stdout); bar[i++] = '#'; //每到15%變換一次顏色 if (i % 15 == 0) { ++j; } //延時50毫秒 usleep(50000); } printf("\n"); return 0;}
一起來看一下結果:
是不是很炫酷,不過看完代碼一定還有許多朋友仍有一些疑惑,下面我來為大家解釋一下上面的代碼的原理:
首先介紹一下緩衝區
緩衝區分位三種:無緩衝,行緩衝,全緩衝。
無緩衝:沒有緩衝,也就是資訊在輸入輸出的時候,立馬輸入或輸出。典型的代表就是標準錯誤流stderr。
行緩衝:當輸入輸出的時候,遇到換行才執行I/O操作。典型的代表是鍵盤的操作。
全緩衝:當輸入輸出寫滿緩衝區才執行I/O操作。典型的代表是磁碟的讀寫。
本次實現進度條使用的是printf函數,printf輸出函數是一個行緩衝函數,先寫到緩衝區,滿足條件就將緩衝區刷到對應檔案中。滿足下列條件之一,緩衝區都會重新整理:
(1)緩衝區填滿
(2)寫入的字元中有’\n”\r’
(3)調用fflush重新整理緩衝區
(4)調用scanf從緩衝區擷取資料時,也會重新整理新緩衝區。
由於輸出函數是行緩衝類型的。所以我們需要使用緩衝區重新整理函數fflush來輸出。否則我們看到的進度條將是一段一段輸出的。
還有兩個符號需要區分:‘\n”\r’。他們有不同的含義。‘\n’表示的是換行,將游標指向下一行的開頭位置。\r則是每次回到行首。如果我們使用\n 進度條的效果就會是下面這樣:
[# ][1%][\][## ][2%][-][### ][3%][/][#### ][4%][|]
**usleep函數** 重新整理了緩衝區之後,如果並沒有加上睡眠函數,結果將一次性輸出來。我們就看不到進度條的載入過程。 這裡統一總結一下Linux睡眠函數: 標頭檔:#include <unistd.h> 以 秒為單位:unsigned int sleep( unsigned int seconds ); 以 微秒為單位:int usleep ( useconds_t usec ); 以 四分之一毫秒為單位:extern void delay( unsigned int msec )
最後介紹一下輸出顏色的設定:
printf函數可以通過輸出特定的逸出序列來實現輸出字元的顏色和狀態。
逸出序列以控制字元’ESC’開頭。該字元的ASCII碼十進位表示為27,十六進位表示為0x1B,八進位表示為033。多數逸出序列超過兩個字元,故通常以’ESC’和左括弧’[‘開頭。該起始序列稱為控制序列引導符(CSI,Control Sequence Intro),通常由 ’\033[‘ 或 ’\e[‘ 代替。
一般格式如下:(顯示方式指的是樣式,前景色彩是30+顏色值,背景色是40+顏色值,字元m表示結束)
\033[顯示方式;前景色彩;背景色m + 輸出字串
或者
\e[顯示方式;前景色彩;背景色m + 輸出字串
常見參數如下:
顯示方式:0(預設)、1(粗體/高亮)、22(非粗體)、4(單條底線)、24(無底線)、5(閃爍)、25(無閃爍)、7(反顯、翻轉前景色彩和背景色)、27(無反顯)
顏色:0(黑)、1(紅)、2(綠)、 3(黃)、4(藍)、5(洋紅)、6(青)、7(白)
更詳細輸出顏色設定的知識參考這位大佬的部落格:printf輸出顏色設定
朋友們,瞭解了這些知識之後,趕快去實踐一下吧。