Linux中的軟件安裝進度條怎么搞?
一、回車與換行
換行是換到下一行的當前位置,一般用\n表示?;剀囀腔氐疆斍靶械拈_始,一般用\r表示。
但一般在語言,比如C語言中,用\n代表換行+回到開始。
二、緩沖區(qū)
先來看兩段代碼及其現(xiàn)象。
第一段代碼,代碼很簡單,主要是為了與第二段形成對比。
int main()
{
printf("I am a proc\n");//有\(zhòng)n
sleep(3);
return 0;
}
先打印,再sleep持續(xù)3秒,很自然的結果。
第二段代碼:
int main()
{
printf("I am a proc");//沒有\(zhòng)n
sleep(3);
return 0;
}
第二段代碼運行結果如下,從結果看來是先sleep持續(xù)3s,然后才打印。
事實上,上面的代碼中由于printf在sleep之前,所以printf永遠先于sleep執(zhí)行,但是先執(zhí)行printf不代表先打印。
printf執(zhí)行后,要打印的內容放入緩沖區(qū),但不一定會被立即刷新到屏幕上。
這里要提一下緩沖區(qū)的3種緩沖策略:
- 1.無緩沖:數(shù)據(jù)不緩沖,直接打印到外設中(屏幕、磁盤等等)。
- 2.行緩沖:先保存一行數(shù)據(jù),后續(xù)刷新時按行刷新(遇到\n就把前面的內容刷新到外設)。
- 3.全緩沖:直到把緩沖區(qū)全放滿才會刷新。
再結合上面兩段代碼及現(xiàn)象,可以得出上面打印時采用的是行緩沖(遇到\n就把要打印的內容打印在屏幕上)。
三、倒計時的程序
如果每次打印完都回車,就相當于在第一個位置打印一個數(shù)字后,又回到該位置,繼續(xù)打印下一個數(shù)字。這樣就可以實現(xiàn)倒計時的效果。
int main()
{
int count = 3;
while(count >= 0)
{
printf("%d\r", count--);
sleep(1);
}
return 0;
}
但結果如下,并沒有打印結果,想到行緩沖的規(guī)則,原來是因為打印的內容一直都沒有換行,所以內容一直存在緩沖區(qū)內,不會打印出來。
這里可以用fflush函數(shù)強行讓屏幕刷新,就可以實現(xiàn)想要的效果了。
使用fflush刷新stdout(即屏幕的文件流),使每次進入緩沖區(qū)的內容被立即打印出來。
int main()
{
int count = 3;
while(count >= 0)
{
printf("%d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}
效果如下
但如果是兩位或更多位的倒計時,就會出現(xiàn)如下的問題:
int main()
{
int count = 10;
while(count >= 0)
{
printf("%d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}
因為每次回車都回到第一個字符,所以第二位的0一直沒有改變。
只需用printf的格式控制即可。
int main()
{
int count = 10;
while(count >= 0)
{
//控制輸出兩位字符
printf("%2d\r", count--);
fflush(stdout);
sleep(1);
}
return 0;
}
運行效果如下:
四、進度條程序
void ProcBar()
{
int i = 0;
char proc[102];
memset(proc, '\0', sizeof(proc));
while(i <= 100)
{
//C語言格式控制時默認右對齊,所以要在前面加-變成左對齊
printf("[%-100s] [%d%%]\r", proc, i);
fflush(stdout);//刷新屏幕打印
proc[i] = '#';
usleep(100000);//以微秒為單位的sleep
i++;
}
printf("\n");
}
int main()
{
ProcBar();
return 0;
}