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