在Linux下實現簡易進度條

本文將要概述

  1. printf的緩衝區問題;
  2. \r和\n的區別;
  3. 如何實現一個簡易的進度條;

奇怪的現象

進度條是安裝和下載軟件中常見的部分,它可以表示軟件安裝或下載了多大,能給客戶一種直觀的感受,今天我們就來實現一個簡易的進度條,基本構思是這樣的,我們定義一個大小爲102的字符數組,其中100個用來存儲‘#’,每跑了進度條的1%它就會在字符數組中增長一個該符號。還有兩塊空間用於存放’\0’,和防止死循環問題(這是因爲控制循環的變量被定義在數組的後面一塊空間,對數組訪問造成了越界的話很有可能修改這塊空間的值,從而造成不可預料的後果)所以我們多開闢一塊空間,避免這種情況的發生。

程序的思路是這樣的,每一次循環都往字符數組中的當前位置寫入’#’,並將控制循環變量+1,在寫入’#’的下一個人位置寫入’\0’,防止打印字符數組時出現亂碼。循環次數控制在100次,每輸入1行後我們輸入\r對其清空,由於延時時間段和人眼的視覺暫留效應,你會看到進度條是一個一個#增長的。
理論上你應該看到這樣的效果
[# ]
[## ]
.
.
.
[############################## ]
[############################### ]
[################################]
代碼如下
這裏寫圖片描述
由於本人這裏沒有截動態圖的軟件,當程序寫好後通過gcc編譯成可執行文件直接執行你會看到進度條並不會像你想象的那樣增長。它是一次好幾個#號的增長直到#增長到100個位置。

這是爲什麼呢????????
下面我們就來揭祕一下這個現象的原因!!!!!

printf的緩衝區問題

出現上面這種原因首先肯定是由於\r的效果,我們再來修改一下程序,把\r換成\n看看會出現什麼現象。
這裏寫圖片描述

真是不吹不黑,咱們來看一下效果,特別是#每次的增長個數;
這裏寫圖片描述

這時我只截圖一部分的效果。

結合着\n和\r的現象我們來引入一個知識點,printf的緩衝區問題

出現上面的兩種情況,是因爲printf是一個行緩衝函數,當我們用printf打印時,先寫到緩衝區,如果緩衝區沒有被則先不打印到屏幕上,直到緩衝區刷新了後纔會輸出到屏幕上。

刷新緩衝區只要滿足下面任意一個條件即可:
1. 緩衝區填滿
2. 寫入的字符中有‘\n’
3. 調用fflush手動刷新緩衝區
4. 調用scanf要從緩衝區中讀取數據時,也會將緩衝區內的數據刷新

可見每次我們寫入\r是不能夠刷新緩衝區的,只會等緩衝區慢後纔會將字符串打印到屏幕上,那麼我們想要實現一個進度條,就不能夠用\n字符,我們必須要在一行上對緩衝區進行刷新,於是我們每次寫入到緩衝區時,都用fflush函數刷新一下緩衝區,問題是不是就能解決了呢?實踐出真知,還是讓我們修改下代碼看看結果吧!

事實是大功告成了!!!
這裏寫圖片描述

所修改的代碼
這裏寫圖片描述
由於printf是輸出緩衝區,所以我們需要刷新下stdout,我們可以男人(man)一下看看這個stdout是幹什麼的。
這裏寫圖片描述

總結

好了,今天我們主要談到了printf的輸出緩衝區的問題,進度條的實現依賴於每次寫進緩衝區後都要刷新緩衝區,使緩衝區中的字符輸出到屏幕上。

Makefile的使用:http://blog.csdn.net/bit_clearoff/article/details/53966718

vim編輯器http://blog.csdn.net/bit_clearoff/article/details/53884356

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章