目錄
一,進(jìn)度條的必備知識(shí)
1,緩沖區(qū)的粗略介紹
2,回車與換行
二,進(jìn)度條的初步制作
1,進(jìn)度條的初步礦建
2,進(jìn)度條的版本一
3,進(jìn)度條的版本二
一,進(jìn)度條的必備知識(shí)
1,緩沖區(qū)的粗略介紹
? ? ? ??緩沖區(qū)是內(nèi)存的一部分空間,用于臨時(shí)存儲(chǔ)輸入和輸出的數(shù)據(jù)。它可分為輸入緩沖區(qū)和輸出緩沖區(qū)。每當(dāng)我們輸入數(shù)據(jù)時(shí)都是往輸入緩沖區(qū)中存放數(shù)據(jù),當(dāng)刷新緩沖區(qū)時(shí),數(shù)據(jù)將會(huì)從緩沖區(qū)中拿出輸入到某個(gè)變量中。每當(dāng)我們輸出數(shù)據(jù)時(shí),系統(tǒng)將會(huì)把數(shù)據(jù)輸出到輸出緩沖區(qū)中,當(dāng)刷新輸出緩沖區(qū)時(shí),數(shù)據(jù)將會(huì)從輸出緩沖區(qū)輸出到指定地方。
? ? ? ? 其中,緩沖區(qū)的刷新時(shí)機(jī)是不同的。行緩沖會(huì)在遇到換行符時(shí)刷新,全緩沖會(huì)在緩沖區(qū)寫滿時(shí)刷新,而無緩沖則沒有緩沖區(qū),代表是系統(tǒng)調(diào)用。在C/C++中,通常用 fflush(FILE* stream) 來強(qiáng)制刷新指定流的緩沖區(qū)。
? ? ? ? C/C++中類似于sleep函數(shù)功能控制的就是緩沖區(qū),當(dāng)系統(tǒng)調(diào)用到sleep是,將會(huì)被緩沖區(qū)暫時(shí)保存起來,一旦sleep運(yùn)行完畢之后緩沖區(qū)才刷新。進(jìn)度條有時(shí)控制的就是緩沖區(qū)的刷新時(shí)間。
2,回車與換行
? ? ? ? “ 回車 ” 是把光標(biāo)從當(dāng)前位置直接指向最開頭位置。“ 換行?” 是把光標(biāo)從當(dāng)前位置直接指向下一行同一列的位置。我們?cè)贑語言階段常用的 “ \n?” 指的是?換行?+ 回車。而 “ \r ” 只表示回車。
二,進(jìn)度條的初步制作
1,進(jìn)度條的初步礦建
? ? ? ? 首先,我們先來編寫進(jìn)度條的簡(jiǎn)單倒計(jì)時(shí)程序,這就需要運(yùn)用回車和sleep來控制程序的運(yùn)行。
#include <iostream>
#include <iomanip> //setw的頭文件
#include <unistd.h> //usleep()的頭文件,對(duì)應(yīng)參數(shù)單位為微秒? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
#include <cstdio>
using namespace std;
int main()
{
? ? int n = 10;
? ? while (n >= 0) {
?? ??? ?cout << left << setw(2) << n << '\r'; //跟C語言中printf("%-2d\r", n)效果一樣
? ? ? ? fflush(stdout); ? //強(qiáng)制刷新輸出緩沖區(qū)
? ? ? ? n--;
? ? ? ? usleep(500000); ? ?//這里我們控制緩沖時(shí)間為0.5秒
?? ?}
? ? cout << endl;
? ? return 0;
}
? ? ? ? 下一步,要思考進(jìn)度條的框架設(shè)計(jì)。這里的進(jìn)度條將外圍用 " = " 表示進(jìn)度的加載,外圍設(shè)置了百分比顯示加載數(shù)據(jù)。用 "|/-\" 來表示其中的加載,即順時(shí)針旋轉(zhuǎn)。
2,進(jìn)度條的版本一
? ? ? ? 首先,外面設(shè)置一個(gè)頭文件 "process.h" 進(jìn)行必要的設(shè)置
#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
using namespace std;#define Body '='? ?//使用body來表示進(jìn)度
#define Head '>'? ?//Head表示目前加載的終點(diǎn),這里用 ' > ' 表示void process1();? //進(jìn)度條函數(shù)
? ? ? ? 下面,進(jìn)行進(jìn)度功能的編寫。這里使用 usleep 功能來控制進(jìn)度的的運(yùn)行,這里需注意的是輸出緩沖區(qū)的刷新。
void process1()
{? ? //用lable表示進(jìn)度條的加載
? ? string lable("|/-\\");??
? ? string nums;
? ? int count = 0;
? ? int lablesize = lable.size();
? ? nums.push_back(Head);
? ? while (count <= 100)
? ? {
? ? ? ? cout << "[" << left << setw(100) << nums << "]";
? ? ? ? cout << "[" << "%" << count << "]";
? ? ? ? cout << "[" << lable[count % lablesize] << "]" << '\r';
? ? ? ? fflush(stdout);
? ? ? ? nums.clear();
? ? ? ? count++;
? ? ? ? nums.append(count, Body);
? ? ? ? if (count < 100)
? ? ? ? {
? ? ? ? ? ? nums.push_back(Head);
? ? ? ? }????????//這里我們?cè)O(shè)置每0.6秒加載一次
? ? ? ? usleep(60000);?
? ? }
? ? cout << endl;
}
運(yùn)行最終結(jié)果:
[====================================================================================================][%100][|]
3,進(jìn)度條的版本二
? ? ? ? 進(jìn)度條一般都是運(yùn)用在一種應(yīng)用上,表示應(yīng)用的加載過程。很顯然,版本一的進(jìn)度條只是無腦運(yùn)行,不知道程序進(jìn)度是多少,即沒有依附應(yīng)用進(jìn)度,比如下載程序,這時(shí)的進(jìn)度條需依附于下載進(jìn)度來跟進(jìn)。
? ? ? ? 頭文件 "process.h" 添加如下:
#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
using namespace std;#define Body '='
#define Head '>'
#define Max 103
#define FileSize 1024*1024*1024? //設(shè)置FileSize文件內(nèi)存為1G,表示下載程序的總大小typedef void (*callback_t)(double);? //利用函數(shù)指針來進(jìn)行封裝進(jìn)度運(yùn)用
void download(callback_t);? //模擬一種下載進(jìn)度
void process2(double rate); //進(jìn)度條跟進(jìn)程序
? ? ? ? 這里,在設(shè)置download下載時(shí)要將每一次的下載進(jìn)度傳遞給進(jìn)度條讓其顯示百分比。
void download(callback_t cb)? ?//利用回調(diào)函數(shù)的形式設(shè)置進(jìn)度
{
? ? srand(time(0)*1024);
? ? int total = FileSize;
? ? while (total)
? ? {
? ? ? ? //下面表示一次下載動(dòng)作
? ? ? ? usleep(10000);
? ? ? ? int one = rand() % (1024 * 1024 * 5);
? ? ? ? total -= one;
? ? ? ? if (total < 0)?
? ? ? ? {
? ? ? ? ? ? total = 0;
? ? ? ? }
? ? ? ? //表示當(dāng)前的進(jìn)度
? ? ? ? int download = FileSize - total;
? ? ? ? double rate = (download * 1.0 / (FileSize)) * 100.0;
? ? ? ? cb(rate); //每一次進(jìn)度條的傳遞
? ? }
}
進(jìn)度條設(shè)置時(shí)要說明以下幾點(diǎn):
????????1,我們使用?"|/-\\" 表示進(jìn)度跟進(jìn)時(shí)是根據(jù)下載進(jìn)度進(jìn)行的,與當(dāng)前的進(jìn)度無關(guān)。
????????2,進(jìn)度條的總設(shè)置需與下載程序緊緊聯(lián)系。比如當(dāng)程序加載完時(shí),“ > ” 進(jìn)度條中表示進(jìn)? ? ? ? ? 度運(yùn)行的就要停止,即刪除。
????????3,在輸出進(jìn)度運(yùn)行過程,我們可添加其色彩表示美觀,鏈接:色彩文本的增添
void process2(double rate)
{? ??//用lable表示下載任務(wù)一直在跟進(jìn)
? ? string lable("|/-\\");?? ??//注意,這里要保留之前的進(jìn)度,需設(shè)置靜態(tài)
? ? static char buffer[Max] = { 0 };
? ? static int cnt = 0;
? ? if (rate <= 1.0)
? ? {
? ? ? ? buffer[0] = Head;
? ? }
? ? printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]);? //設(shè)置色彩,這里我們?cè)O(shè)置高亮/加粗,青色背景,紅色字體的色彩
? ? fflush(stdout);? ? //下面控制進(jìn)度的跟進(jìn)
? ? buffer[(int)rate] = Body;
? ? if ((int)rate + 1 < 100)
? ? {
? ? ? ? buffer[(int)(rate + 1)] = Head;
? ? }
? ? if (rate >= 100.0)
? ? {
? ? ? ? cout << endl;
? ? }
? ? cnt++;
? ? cnt %= lable.size();
}
總代碼如下:文章來源:http://www.zghlxwxcb.cn/news/detail-757493.html
#include "process.h"
//版本一
void process1()
{
string lable("|/-\\");
string nums;
int count = 0;
int lablesize = lable.size();
nums.push_back(Head);
while (count <= 100)
{
cout << "[" << left << setw(100) << nums << "]";
cout << "[" << "%" << count << "]";
cout << "[" << lable[count % lablesize] << "]" << '\r';
fflush(stdout);
nums.clear();
count++;
nums.append(count, Body);
if (count < 100)
{
nums.push_back(Head);
}
usleep(60000);
}
cout << endl;
}
//版本二
void download(callback_t cb)
{
srand(time(0) * 1024);
int total = FileSize;
while (total)
{
usleep(10000);
int one = rand() % (1024 * 1024 * 5);
total -= one;
if (total < 0)
{
total = 0;
}
int download = FileSize - total;
double rate = (download * 1.0 / (FileSize)) * 100.0;
cb(rate);
}
}
void process2(double rate)
{
static string lable("|/-\\");
static char buffer[Max] = { 0 };
static int cnt = 0;
if (rate <= 1.0)
{
buffer[0] = Head;
}
printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]);
fflush(stdout);
buffer[(int)rate] = Body;
if ((int)rate + 1 < 100)
{
buffer[(int)(rate + 1)] = Head;
}
if (rate >= 100.0)
{
cout << endl;
}
cnt++;
cnt %= lable.size();
}
int main()
{
//process1(); //使用進(jìn)度條粗略版本一
download(process2); //使用進(jìn)度條進(jìn)化版本二
return 0;
}
????????最后,要說明的是,以上程序都是在Linux系統(tǒng)下運(yùn)行進(jìn)行的,在VS或其它編譯器下可能會(huì)出現(xiàn)錯(cuò)誤消息,這時(shí)因?yàn)椴煌脚_(tái)支持的C標(biāo)準(zhǔn)或系統(tǒng)設(shè)置不同而造成的差異。文章來源地址http://www.zghlxwxcb.cn/news/detail-757493.html
到了這里,關(guān)于【Linux系統(tǒng)編程】進(jìn)度條的編寫的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!