衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

教你在Linux上寫一個進度條小程序

dyquk4xk2p3d ? 來源:入門小站 ? 2023-01-29 11:37 ? 次閱讀

一、前言

Linux 上寫下一個簡易的進度條小程序。

成品展示

93c0b498-96c4-11ed-bfe3-dac502259ad0.gif

今天的內容比較輕松,只需要了解兩個知識點,這個小程序就很容易寫出來了,讓我們開始今天的學習。

二、理解 ‘ ’ 與 ‘ ’

C 語言中有很多字符,而字符大體分為兩類:可顯字符、控制字符。

控制字符不可顯示,例如 和 就是控制字符。

而在我們平時打字時,一行寫滿了需要換行,但是新起一行有很多種,例如:

93cdda7e-96c4-11ed-bfe3-dac502259ad0.png

這樣雖然新起一行了,但是不是我們想要的結果。

我們通常新起一行是在第二行的最左端,但是對于這個結果其實有兩個操作:

1.跳轉到第二行

2.回到第二行的最左端

有了這個基本概念,再來談 和 的作用:

:回車 - 回到文本行的開頭

:換行 - 新起一行

所以,其實我們平時泛指的換行實際上是 回車 + 換行

且在語言范疇下,例如 C 語言,換行就可以達到回車 + 換行的效果。在平常,這一操作還是兩個步驟。

三、行緩沖

行緩沖這個概念認識。

1、提出問題

首先先了解一下兩個庫函數:

sleep:Linux 下的休眠函數,單位是秒。頭文件為#include

fflush:刷新緩沖區

代碼 1:

#include
intmain()
{
printf("helloxxx");
sleep(3);
return0;
}

現象:

93e6f360-96c4-11ed-bfe3-dac502259ad0.gif

分析:

光標停留在文本行的開頭,但是字符串沒有被打印。

反而像是 sleep 函數先起作用,然后 printf 函數再從光標處開始打印。

打印完之后,shell 提示符緊跟著字符串后顯示。

代碼 2:

#include
intmain()
{
printf("helloxxx
");
sleep(3);
return0;
}

現象:

93f45a50-96c4-11ed-bfe3-dac502259ad0.gif

分析:

printf 打印的字符串先顯示在終端上,光標位于字符串的下一行。

sleep 函數使程序休眠 3 秒后,shell 提示符從光標位置開始顯示。

代碼 3:

#include
intmain()
{
printf("helloxxx
");
sleep(3);
return0;
}

現象:

93fc5f3e-96c4-11ed-bfe3-dac502259ad0.gif

分析:

printf 打印的字符串沒有顯示到終端,光標一直停留在該打印字符串的一行

sleep 函數休眠三秒后,shell 提示符直接打印在了屏幕上。并沒有看到字符串。

觀察上面的現象,我們提出幾個問題:

代碼 1 好像是先執行了 sleep ,在執行 printf ,是這樣嗎?

代碼 2 加上了 ‘ ’ ,字符串一開始就顯示了,為什么?

代碼 3 好像什么都沒打印,這是為什么?

在解答這些問題之后,我們先了解一下行緩沖。

2、認識行緩沖

在內存中預留了一塊空間,用來緩沖輸入或輸出的數據,這個保留的空間被稱為緩沖區。

我們之前或多或少都聽說過緩沖區。

在代碼 1 中,由于程序是按照數據執行的,所以必定是先執行 printf 。

但是數據沒有顯示,所以這時候,數據就一定被保存在某個位置,保存的位置就是緩沖區。

而要讓數據顯示,是需要刷新緩沖區的。

行緩沖是緩沖區刷新策略的一種,在行緩沖模式下,當輸入和輸出中遇到 ‘ ’ 換行時,就會刷新緩沖區。

有了這個概念,我們繼續分析問題。

3、解答與拓展

解答

問題 1:代碼 1 好像是先執行了 sleep ,在執行 printf ,是這樣嗎?

當然不是。由于程序是按照順序執行的,所以必定是先執行完 printf 在執行 sleep 。

而數據沒有被顯示出來的原因是:數據保存在緩沖區中,但是沒有主動刷新,當程序退出后,保存在緩沖區中的數據被自動刷新出來了。

所以才會造成這種現象。

問題 2:代碼 2 加上了 ,字符串一開始就顯示了,為什么?

這里由于是直接往顯示器上打印,所以采用的刷新方式為行緩沖。

所以執行碰到 ‘ ’ 時,就會把在緩沖區中的 (換行符之前) 的內容全部刷新出來。

所以這段代碼一開始就會有數據顯示,然后再 sleep 休眠。

問題 3:代碼 3 好像什么都沒打印,這是為什么?

之前說過 是換行,所以當 printf 遇到 時,就把光標移到開頭。sleep 睡眠后,當程序退出,shell 打印提示符時,就覆蓋了字符串。

拓展

數據真的是臨時保留在緩沖區里的嗎?光標如何理解?

我們用一段代碼來理解這兩個問題:

#include
#include
intmain()
{
printf("helloxxx
");
fflush(stdout);
sleep(3);
return0;
}

現象:

94037e36-96c4-11ed-bfe3-dac502259ad0.gif

觀察現象,我們發現當我們使用fflush主動刷新緩沖區后,數據就顯示在了屏幕上;且因為 ‘ ’ 的原因,光標指向字符串開頭;當打印 shell 提示符時,就直接從光標位置開始覆蓋。

所以對于這兩個問題,我們已經得到了答案:

1.數據被臨時保存在于緩沖區中,通過刷新就可以顯示

2.數據是從光標位置開始打印的。

一句話理解光標:光標和顯示器匹配,光標在哪里,顯示器打印的時候就從哪里開始打印

4、倒計時

基于對上面的理解,我們先實現一個簡單的倒計時。

倒計時就是在屏幕上不斷顯示數字,每次在同一位置顯示,并將之前的數據覆蓋。

既然是每次要從頭開始覆蓋,那么就可以用 ‘ ’ 來實現每次回到行首,并且可以通過相應的格式化控制顯示多位打印。

但是 ‘ ’ 不會主動刷新,所以要用fflush函數主動刷新緩沖區。

在每次刷新之后,使用 sleep 函數,間隔一定的時間。

由此,我們可以很輕松寫出代碼,例如寫一個從 10 開始的倒計時:

#include
#include

intmain()
{
inti=10;
for(;i>=0;i--){
//位寬控制,
回到開頭
printf("%2d
",i);
fflush(stdout);//主動刷新
sleep(1);//休眠
}
printf("
");//換行,打印提示符
return0;
}
94115808-96c4-11ed-bfe3-dac502259ad0.gif

四、進度條

好了,接下來進入正題,我們開始寫進度條。

進度條樣式

主體樣式為兩個中括號包裹,中間=>推進的方式呈現,比如:[======>]

主體右側中括號位置保持不變,中間元素不斷推進,比如:[=> ]

顯示當前加載進度,用[num%]顯示,num 隨著進度條的不斷推進而變化

顯示加載樣式,可以利用一個旋轉的字符,例如[]的樣式,順時針不斷旋轉

大約呈現狀態為:[========>] [15%] []

采用多文件

文件存放在proc目錄中

proc.h :函數聲明

proc.c :進度條邏輯

main.c :函數調用

makefile準備

由于采用多文件,所以依賴關系可以寫成依賴文件列表的樣式:

941a4648-96c4-11ed-bfe3-dac502259ad0.png

分塊邏輯

1.進度條主體

預留進度條大小為 100 個=,外加 1 個>,加上保存'?'的位置,用數組存儲為 102 個單位。

進度條是一行中的,所以需要用到' ',每次都需要使用fllush主動刷新緩沖區。

每次刷新出數據之后,將 = 填充到數組中,并且顯示 > 。在最后一次顯示時,控制 > 不要顯示。

然后休眠一小會。由于休眠用 sleep 函數太慢。所以可以用 usleep 函數休眠,usleep 函數的參數單位是微秒。

根據這個寫出代碼:

942199a2-96c4-11ed-bfe3-dac502259ad0.png942b83a4-96c4-11ed-bfe3-dac502259ad0.gif

2.百分比顯示

%% 顯示為一個 % ,而 %d 為數字,這步很簡單,只要在 printf 語句中加上內容:

printf("[%-100s][%d%%]
",bar,i);

3.旋轉光標

光標旋轉方向為順時針旋轉,那么旋轉時就可以用數組保存。

旋轉每次顯示內容分別為| / - ,\代表一個 ,因為和 結合的會被解析為轉義字符,將其保存到字符串中。

而由于字符串一共就四個字符,所以輸出的時候需要控制輸出位置。

代碼:

constchar*str="|/-";//字符串
printf("[%-100s][%d%%][%c]
",bar,i,str[i%4]);//輸出語句

完整代碼

proc.h

#pragmaonce

#include

externvoidprocess();

proc.c

#include"proc.h"
#include
#include

#defineSIZE102//數組大小
#defineSTYLE'='
#defineFLAG'>'

voidprocess()
{
constchar*str="|/-";
charbar[SIZE];
memset(bar,'?',sizeof(bar));
inti=0;
while(i<=?100)?{
??????printf("[%-100s][%d%%][%c]
",?bar,?i,?str[i?%?4]);?//?格式控制
??????fflush(stdout);?//?刷新
??????bar[i++]?=?STYLE;?//?填充數據
??????if?(i?!=?100)?{
??????????bar[i]?=?FLAG;?//?如果不是最后一次則顯示?>
}
usleep(100000);//休眠
}
printf("
");
}

test.c

#include"proc.h"

intmain()
{
process();
return0;
}

進度條展示

93c0b498-96c4-11ed-bfe3-dac502259ad0.gif

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11345

    瀏覽量

    210392
  • C語言
    +關注

    關注

    180

    文章

    7614

    瀏覽量

    137713
  • 字符
    +關注

    關注

    0

    文章

    234

    瀏覽量

    25262
  • 函數
    +關注

    關注

    3

    文章

    4346

    瀏覽量

    62971
  • 小程序
    +關注

    關注

    1

    文章

    239

    瀏覽量

    12263

原文標題:教你在 Linux 上寫一個進度條小程序

文章出處:【微信號:良許Linux,微信公眾號:良許Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    關于進度條

    我用的labview8.6,初學者,在那能找到進度條??!
    發表于 10-28 11:35

    如何在程序中加進度條顯示程序運行的進度

    由于數據很大,程序運行的時間很長,想在程序中加進度條顯示程序運行的
    發表于 08-14 22:30

    如何為運行得很慢的程序添加進度條或者任何提示?

    問題是:該程序的循環底層VI中,該VI用戶不可更改。較頂層的程序均不存在循環。為了排解等待程序運行過程中的無聊,想加個進度條,或者任何會動
    發表于 09-26 16:59

    請問怎么用進度條顯示程序進度

    怎么用進度條顯示程序進度
    發表于 12-24 10:02

    如何顯示vi程序運行的進度條

    程序調用mtalab腳本節點,運行很慢,想設計進度條,實時顯示運行進度,求各位大神幫忙
    發表于 04-01 13:53

    labview的進度條

    這是labview的進度條程序,比較好用
    發表于 08-04 14:30

    labview進度條

    我用labview2017做了文件解壓和復制的vi,解壓過程中不知道真實的解壓進度,怎么才能做一個真實的進度條,要真是的,不是自己規定的
    發表于 04-26 09:10

    為什么燒不了程序,進度條直不動?

    怎么燒不了程序...進度條直不動啊...
    發表于 07-18 05:45

    怎么設置進度條?

    RT!比如 我創建隨意長度的進度條然后我知道文件的大小 當把這個文件里的數據讀完后進度條
    發表于 08-22 04:35

    如果更新太快,進度條對象無法正確呈現?

    嗨,所有,我正在更新和諧進度條對象的基礎定時器值。如果我使用的時間小于1500毫秒,進度條對象背景和邊框不能正確渲染。這段視頻更清楚地
    發表于 09-20 06:18

    HarmonyOS實戰——ProgressBar進度條組件基本使用

    ProgressBar案例——點擊進度條增加實際進度值需求分析:每單擊進度條組件時,進度條就加 5% 的
    發表于 09-22 23:31

    Linux下實現進度條程序,通過makefile進行編譯

    1. Linux下實現進度條程序。 通過makefile進行編譯。 建議自主完成彩色的
    發表于 03-12 16:31 ?2156次閱讀

    Linux基礎教程之linux wget下載進度條變成多行顯示如何解決

    之前為了 解決Putty客戶端連接到CentOS之后顯示亂碼 的問題,設置了 LANG=zh_CN.UTF-8 之后,使用wget下載的時候,wget下載進度條異常,竟然不能在
    發表于 10-31 17:04 ?19次下載

    如何利用ChatGPT快速實現控制臺進度條小工具?

    控制臺程序執行些耗時任務時,需要向用戶顯示當前任務執行的進度,以提供清晰的感知。比如下載程序
    的頭像 發表于 01-18 13:41 ?1034次閱讀
    如何利用ChatGPT快速實現<b class='flag-5'>一</b><b class='flag-5'>個</b>控制臺<b class='flag-5'>進度條</b>小工具?

    【AWTK使用經驗】如何設計立體電池進度條?

    AWTK是基于C語言開發的跨平臺GUI框架。《AWTK使用經驗》系列文章將介紹開發AWTK過程中些常見問題與解決方案,例如:如何加載外部資源?如何設計自定義進度條?這些都會在系列文章進行解答
    的頭像 發表于 04-18 08:25 ?508次閱讀
    【AWTK使用經驗】如何設計立體電池<b class='flag-5'>進度條</b>?
    百家乐官网看澳门| 平舆县| 联合百家乐官网的玩法技巧和规则| 威尼斯人娱乐场xpjgw5xsjgw| 百家乐官网庄闲当哪个好| 东营区百家乐艺术团| 百家乐官网美女视频聊天| 大丰收百家乐的玩法技巧和规则 | 新疆| 百家乐21点德州扑克| 百家乐官网娱乐开户| 澳门百家乐网上赌城| 百家乐官网庄闲概率| 大发888娱乐城m88| 真人百家乐官网最高赌注| 克拉玛依市| 澳门百家乐必赢技巧| 百家乐官网必胜密| 大发888下载17| 免费百家乐官网计划软件| E乐博| 百家乐有没有单机版的| 百家乐官网出庄的概率| 宝龙线上娱乐城| 百家乐六手变化混合赢家打法| 百家乐官网黑牌靴| 大发888体育娱乐场| 百家乐盈利分析路单| 百家乐官网平台开户哪里优惠多 | 做生意戴什么珠子招财| 涿州市| 二八杠小游戏| 百家乐打法分析| 百家乐官网技巧之微笑心法| 大发888客户端的软件| 永利博百家乐现金网| 网络百家乐官网骗局| 大发888官方ylc8| 澳门百家乐职业赌客| 武汉百家乐官网庄闲和| 米林县|