[Linux]制作進度條小程序
C語言中的\n和\r字符
C語言中字符分為兩種:
- 可顯字符
- 控制字符
其中可顯字符就是字符a這類的字符,控制字符就是\n這種控制字符。
對于我們制作進度條,我們只需要關(guān)注兩個控制字符:
- \r – 進行回車操作
- \n – 進行換行加回車操作
說明: \n本身是換行字符,但是C語言本身將其解析成了換行加回車。
為了更好地體會字符\r和\n的作用,我們需要做一些測試,為了方便進行編譯,創(chuàng)建makefile文件,文件內(nèi)容如下:
mytest:test.c
gcc -o mytest test.c
.PHONY:clean
clean:
rm -f mytest
首先執(zhí)行如下代碼:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world");
sleep(3);
fflush(stdout);
return 0;
}
說明:
- fflush(stdout)是將標準輸出緩沖區(qū)刷新,便于觀察現(xiàn)象。
- sleep為Linux系統(tǒng)的休眠函數(shù)。
執(zhí)行結(jié)果如下:
在打印完hello world
后,程序休眠,"光標"在同一行的下一個位置
休眠結(jié)束后,將會接著從光標位置開始打印,因此打印的[qxm@aliyun-centos review]$
命令行提示符,緊跟在hello world
其后。
再執(zhí)行如下代碼:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world\n");
sleep(3);
return 0;
}
執(zhí)行結(jié)果如下:
由于\n被C語言解析成換行加回車,在打印完hello world
后程序休眠,"光標"會到下一行的開始的位置。
休眠結(jié)束后,將會接著從光標位置開始打印,因此[qxm@aliyun-centos review]$
命令行提示符是在下一行的行首打印。
最后執(zhí)行如下代碼:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world\n");
sleep(3);
return 0;
}
說明:
- fflush(stdout)是將標準輸出緩沖區(qū)刷新,便于觀察現(xiàn)象。
- sleep為Linux系統(tǒng)的休眠函數(shù)。
執(zhí)行結(jié)果如下:
由于\r為回車,在打印完hello world
后程序休眠,"光標"會回到行首。
休眠結(jié)束后,將會接著從光標位置開始打印,因此[qxm@aliyun-centos review]$
命令行提示符將原有的hello world
覆蓋了。
緩沖區(qū)的刷新策略
Linux系統(tǒng)下,C語言會將要打印的字符先存放在緩沖區(qū)中,只有將緩沖區(qū)內(nèi)的字符刷新到屏幕上,才能在屏幕上看到,緩沖區(qū)刷新的情況如下:
- 遇到\n會將\n前的所有字符刷新到屏幕上。
- 程序結(jié)束時自動刷新緩沖區(qū)。
對于緩沖區(qū)測試,我們執(zhí)行如下代碼:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world\r");
sleep(3);
return 0;
}
執(zhí)行結(jié)果如下:
因為緩沖區(qū)沒有刷新,因此程序休眠時,沒有任何打印。
程序執(zhí)行結(jié)束后,緩沖區(qū)被自動刷新,hello world
被打印出來,但是由于\r回車將"光標"退回到行首,因此命令提示符的打印將前面的打印覆蓋了。
再執(zhí)行如下代碼:
#include <stdio.h>
#include <unistd.h>
int main()
{
printf("hello world\n");
sleep(3);
return 0;
}
執(zhí)行結(jié)果如下:
由于遇到了\n緩沖區(qū)內(nèi)的數(shù)據(jù)在休眠前刷新了。
程序休眠結(jié)束后,命令行提示符從光標所在位置開始打印。
進行進度條代碼編寫
創(chuàng)建以下文件構(gòu)成代碼結(jié)構(gòu):
- myproc.h – 保存進度條代碼的聲明
- myproc.c – 保存進度條代碼的實現(xiàn)
- main.c – 調(diào)用進度條代碼
myproc.h文件中的核心結(jié)構(gòu)如下:
#pragma once
#include <stdio.h>
extern void process();
myproc.c文件中的核心結(jié)構(gòu)如下:
#include "myproc.h"
void process()
{
//...
}
main.c文件中的核心結(jié)構(gòu)如下:
#include "myproc.h"
int main()
{
process();
return 0;
}
同時創(chuàng)建makefile文件,makefile文件內(nèi)部寫入如下內(nèi)容:
myproc:myproc.c main.c
gcc -o myproc myproc.c main.c
.PHONY:clean
clean:
rm -f myproc
建立好代碼結(jié)構(gòu)后,編寫如下代碼充當圖形化進度條:
#include "myproc.h"
#include <string.h>
#include <unistd.h>
#define STYLE '='
#define ARROW '>'
#define SIZE 101
void process()
{
char buf[SIZE];
memset(buf, 0 , SIZE);
int i = 0;
while(i <= 100)
{
printf("[%-100s]\r", buf);
fflush(stdout);
buf[i++] = STYLE;
if(i != 100 )buf[i] = ARROW;
usleep(100000);
}
printf("\n");
}
首先創(chuàng)建一個字符串用于保存要打印的圖形化進度條buf,對其進行初始化,然后在打印時進行左對齊打印buf并且按100個字符長度打印,
每次打印完回車覆蓋上一次從打印,并且刷新緩沖區(qū)使得打印顯示到屏幕上,使用休眠函數(shù)來充當進度的加載。
打印的效果如下:
除了圖形化進度條還要設(shè)置數(shù)字化進度顯示,因此需要對打印進行修改,如下:
printf("[%-100s][%d%%]\r", buf, i);
增加打印進度百分比作為數(shù)據(jù)化進度顯示,%%將會轉(zhuǎn)義成一個%打印在屏幕上。
打印的效果如下:
最后增添一個旋轉(zhuǎn)光標表示進度條正在不斷執(zhí)行,因此需要對打印再進行修改,得到最終的代碼如下:
#include "myproc.h"
#include <string.h>
#include <unistd.h>
#define STYLE '='
#define ARROW '>'
#define SIZE 101
void process()
{
const char* cursor = "|/-\\";
char buf[SIZE];
memset(buf, 0 , SIZE);
int i = 0;
while(i <= 100)
{
printf("[%-100s][%d%%][%c]\r", buf, i, cursor[i%4]);
fflush(stdout);
buf[i++] = STYLE;
if(i != 100 )buf[i] = ARROW;
usleep(100000);
}
printf("\n");
}
添加了cursor字符串保存旋轉(zhuǎn)光標的樣式,其中\(zhòng)\會轉(zhuǎn)義成一個\,因為旋轉(zhuǎn)光標中是將4個字符循環(huán)打印因此將樣式字符串模4輸出。
最終進度條的演示結(jié)果如下:文章來源:http://www.zghlxwxcb.cn/news/detail-631370.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-631370.html
到了這里,關(guān)于[Linux]手把手教你制作進度條小程序的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!