国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【Linux】Linux第一個(gè)小程序-進(jìn)度條

這篇具有很好參考價(jià)值的文章主要介紹了【Linux】Linux第一個(gè)小程序-進(jìn)度條。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言:

  • 在之前的學(xué)習(xí)中,我們已經(jīng)基本掌握了關(guān)于了 Linux 下的一些工具的使用,接下來我們運(yùn)用之前學(xué)到的知識,我將帶領(lǐng)大家寫了一個(gè)關(guān)于?進(jìn)度條 的小程序來練練手!?。?/span>

【Linux】Linux第一個(gè)小程序-進(jìn)度條


本文目錄

(一)理解 \r && \n

1、可顯字符 和 控制字符

2、代碼演示

(二)緩沖區(qū)的理解

1、什么是緩沖區(qū)

2、為什么要引入緩沖區(qū)

3、代碼演示,引出現(xiàn)象

4、深入理解,解答現(xiàn)象

①緩沖區(qū)的類型

②緩沖區(qū)的刷新

(三)倒計(jì)時(shí)功能的實(shí)現(xiàn)

1、9以內(nèi)的倒計(jì)時(shí)

2、10以內(nèi)的倒計(jì)時(shí)實(shí)現(xiàn)

a)修改版

(四)進(jìn)度條小程序(???)

1、進(jìn)度條樣式說明

2、多文件實(shí)現(xiàn)

3、主體架構(gòu)實(shí)現(xiàn)

4、進(jìn)度的實(shí)現(xiàn)

5、緩沖功能的實(shí)現(xiàn)

(五)總結(jié)


(一)理解 \r && \n

在我們正式的寫進(jìn)度條之間,我先給大家理清一下這兩個(gè)概念,帶大家看看到底什么是?\r \n

1、可顯字符 和 控制字符

在我們之前學(xué)習(xí)的 C語言中,有很多的字符。但是在宏觀上大概可以分為兩類字符,它們分別是:

  • a)可顯字符:當(dāng)我們從鍵盤上輸入這個(gè)字符時(shí),顯示器上就可以顯示這個(gè)字符,即輸入什么就顯示什么。這類字符稱為可顯示字符,如a、b、c、$、+和空格符等都是可顯示字符。
  • b)控制字符:通常表示出現(xiàn)于特定的信息文本中,表示某一控制功能的字符。例如我們今天要講到的? \n \r 等字符

不知道大家發(fā)現(xiàn)沒有,不管是在我們?nèi)粘G么a又或者像我此時(shí)寫文章的時(shí)候,當(dāng)我們寫完一行后若是沒有?自動換行功能 此時(shí)就需要敲下鍵盤中的【Enter】鍵以此來達(dá)到換行的效果??墒菍τ谶@個(gè)按鍵,大家可能都認(rèn)為就是簡單的敲一下鍵盤上的一個(gè)鍵,但是實(shí)際上在計(jì)算機(jī)內(nèi)部是做了兩件事的,即 —— 【換行】+【回車】。具體如下:

  • \n表示新起一行,此時(shí)光標(biāo)位于行末 (換行)
  • \r表示回到當(dāng)前文本行的最開始處(回車)

【Linux】Linux第一個(gè)小程序-進(jìn)度條?

此時(shí)可能就有點(diǎn)小伙伴會有疑惑,說不對呀!我之前寫 C語言的時(shí)候就是 printf打印 \n 之后就可以了呀,你這里怎么說是有兩部呢?

  • 那是因?yàn)楦魑划?dāng)前的語言范疇它呢就把 \n 就默認(rèn)成為了 回車加換行,所以呢你看到的就是這個(gè)樣子

現(xiàn)在我們知道了進(jìn)行“換行操作” 其實(shí)是經(jīng)歷過兩步的。其實(shí)很早之前在我們的老式鍵盤上就已經(jīng)體現(xiàn)出來了,不知道各位小伙伴有沒有仔細(xì)觀察過呢?

【Linux】Linux第一個(gè)小程序-進(jìn)度條?

2、代碼演示

?當(dāng)我們知道現(xiàn)象后,接下來我們就需要去驗(yàn)證一下,看我所說的是否是真的。接下來,我寫幾行代碼給大家演示一下

  • 注意:因?yàn)樵谥暗闹v解中,我們已經(jīng)知道了 【vim】【make\Makefile】以及【gcc】的基本使用,接下來我們就不解釋這些工具的使用了

a)首先,我們的代碼是先寫出基礎(chǔ)的【Makefile】,我們在創(chuàng)建一個(gè)【test.c】文件用來寫代碼

【Linux】Linux第一個(gè)小程序-進(jìn)度條?

?b)緊接著我們先寫【Makefile】,同時(shí)在【test.c】文件中寫入兩行代碼。具體如下:

【Linux】Linux第一個(gè)小程序-進(jìn)度條?

?c)最后,我們可以執(zhí)行這個(gè)程序,看最后的結(jié)果是如何的

【Linux】Linux第一個(gè)小程序-進(jìn)度條?

?現(xiàn)象解釋:

  • 從上我們不難發(fā)現(xiàn)一個(gè)事情。最后帶有 【\r】的一行沒有打印出來。
  • 原因就是因?yàn)椤綷r】將光標(biāo)回到最開始的位置,你可以理解為本來是應(yīng)該打印 【hello hello】,但是光標(biāo)此時(shí)回到最左側(cè),最后刷新顯示的時(shí)候就什么都沒有了!

到此,具體的現(xiàn)象我就帶大家看到了,原因我也給大家分析了。

  • 但是這就完了嗎?其實(shí)并沒有,我們想要充分理解,我們還要學(xué)習(xí)一下關(guān)于緩沖區(qū)的概念

因此,接下來我們將要學(xué)習(xí)的便是關(guān)于緩沖區(qū)的基本知識了?。?!


(二)緩沖區(qū)的理解

1、什么是緩沖區(qū)

  • 緩沖區(qū)又稱為緩存,它是內(nèi)存空間的一部分。也就是說,在內(nèi)存空間中預(yù)留了一定的存儲空間,這些存儲空間用來緩沖輸入或輸出的數(shù)據(jù),這部分預(yù)留的空間就叫做緩沖區(qū)。
  • 緩沖區(qū)根據(jù)其對應(yīng)的是輸入設(shè)備還是輸出設(shè)備,分為輸入緩沖區(qū)和輸出緩沖區(qū)。

2、為什么要引入緩沖區(qū)

那么當(dāng)我們有了關(guān)于緩沖區(qū)的概念之后,此時(shí)我們就會想為什么會引入 “緩沖區(qū)” 這個(gè)概念呢?

舉個(gè)簡單的例子:

  • 當(dāng)我們從磁盤里讀取信息時(shí),我們先把讀出的數(shù)據(jù)放在緩沖區(qū),計(jì)算機(jī)再直接從緩沖區(qū)中取數(shù)據(jù),等緩沖區(qū)的數(shù)據(jù)取完后再去磁盤中讀取,這樣就可以減少磁盤的讀寫次數(shù);
  • 再加上計(jì)算機(jī)對緩沖區(qū)的操作遠(yuǎn)快于對磁盤的操作,故緩沖區(qū)的使用可大大提高計(jì)算機(jī)的運(yùn)行速度。

3、代碼演示,引出現(xiàn)象

有了上述的基本認(rèn)識之后,接下來我們通過簡單的代碼觀察其中的現(xiàn)象,讓大家有直觀的感受,進(jìn)而我們在深入探討

  • 在這之前先認(rèn)識兩個(gè)Linux下的庫函數(shù)

sleep() 函數(shù):——>睡眠

  • 頭文件包含在<unistd.h>
  • 注意區(qū)分一點(diǎn):Windows中的 sleep() 單位是 毫秒;而Linxu中的sleep()單位是?

fflush()函數(shù) ——>?刷新流

  • 該函數(shù)一般用來刷新輸出流 ->stdout
  • 格式:int fflush(FILE *stream);

還是以上述驗(yàn)證字符的代碼為例,我給幾段代碼以及輸出現(xiàn)象,大家先感受一下

a)代碼

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   printf("hello world");
  6                                                                                                                                          
  7   sleep(2);        
  8                   
  9   return 0 ;       
 10 }   

運(yùn)行結(jié)果

現(xiàn)象描述:

  • 以上代碼輸出的最后我們沒有加上【\n】,從結(jié)果我們不難看出,我們要輸出的【hello world】并沒有在第一時(shí)間打印,而是在睡眠2秒后和【命令提示符】一同進(jìn)行打印,這是為何呢?(注意,問題來了喲?。。。?/strong>

b)代碼

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   printf("hello world\n");                                                                                                                                              
  7   sleep(2);        
  8                    
  9   return 0 ;       
 10 }   

運(yùn)行結(jié)果

現(xiàn)象描述:

  • 從上述的結(jié)果我們可以發(fā)現(xiàn):和我們平時(shí)寫的代碼幾乎沒有區(qū)別的,當(dāng)加上sleep()函數(shù),相當(dāng)于在打印輸出完之后讓程序 “延遲” 2秒,然后才會顯示【命令提示符】

c)代碼

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   printf("hello world");
  6   fflush(stdout);                                                                                                                                                  
  7   sleep(2);        
  8                    
  9   return 0 ;       
 10 }   

運(yùn)行結(jié)果

現(xiàn)象描述:

  • 緊接著我們在下行加入了?fflush()?這個(gè)函數(shù),將其放在?sleep()?函數(shù)之前,也就相當(dāng)于是優(yōu)先刷新了一下緩沖流,此時(shí)就可以看到【hello world】立馬先被打印了出來,等上2秒后才顯示的【命令提示符】

d)代碼

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   printf("hello world\r");
  6                                                                                                                                               
  7   sleep(2);        
  8                    
  9   return 0 ;       
 10 }   

運(yùn)行結(jié)果

現(xiàn)象描述:

  • 從上述我們可以觀察到:當(dāng)我們在輸出語句后加上了?\r 時(shí),當(dāng)開始執(zhí)行后程序便開始睡眠, 然后在2秒睡眠后便直接打印出了【命令提示符】(注意:問題又來了喲?。。。?/strong>

e)代碼

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   printf("hello world\r");
  6   fflush(stdout);                                                                                                                                                    
  7   sleep(2);
  8             
  9   return 0 ;
 10 }

運(yùn)行結(jié)果

現(xiàn)象描述:

  • 通過上述現(xiàn)象我們不難發(fā)現(xiàn):通過fflush()刷新流,我們提前顯示了一下需要打印的數(shù)據(jù),此時(shí)就可以清晰的觀察到,其實(shí)我們原本要打印的數(shù)據(jù)是在的,結(jié)果被【命令提示符】覆蓋掉了

4、深入理解,解答現(xiàn)象

從上述的代碼展示以及最后的結(jié)果我們提出了以下幾個(gè)問題,分別是:

  • 不加換行符?\n?時(shí)為何是先睡眠再打?。?/strong>
  • 加上?\n?后數(shù)據(jù)會立刻顯示出來,完成睡眠后才顯示提示符?
  • 加上回車?\r?后觀察不到我們輸出的數(shù)據(jù)。然而刷新一下就有了??

接下來,我會一一為大家解答上述疑惑!??!

  • 在解答之前,我們先來看一些需要大家了解的文字知識!

①緩沖區(qū)的類型

緩沖區(qū)可以分為三種類型:全緩沖、行緩沖和不帶緩沖

  • 注意:在這里我們主要講的是關(guān)于【行緩沖】的基本知識

1、全緩沖

  • 在這種情況下,當(dāng)填滿標(biāo)準(zhǔn)I/O緩存后才進(jìn)行實(shí)際I/O操作。全緩沖的典型代表是對磁盤文件的讀寫。

2、行緩沖

  • 在這種情況下,當(dāng)在輸入和輸出中遇到換行符時(shí),執(zhí)行真正的I/O操作。這時(shí),我們輸入的字符先存放在緩沖區(qū),等按下回車鍵換行時(shí)才進(jìn)行實(shí)際的I/O操作。典型代表是鍵盤輸入數(shù)據(jù)。

3、不帶緩沖

  • 顧名思義,也就是不進(jìn)行緩沖,標(biāo)準(zhǔn)出錯(cuò)情況 【stderr】就是典型代表,這使得出錯(cuò)信息可以直接盡快地顯示出來。

②緩沖區(qū)的刷新

當(dāng)發(fā)生以下情況后,緩沖區(qū)將會執(zhí)行刷新操作:

  • 1、緩沖區(qū)滿時(shí)會自動刷新
  • 2、執(zhí)行特定的函數(shù)時(shí)
  • 3、行緩沖遇到換行符時(shí)也會刷新
  • 4、關(guān)閉文件時(shí),也會自動刷新

可見,緩沖區(qū)滿或關(guān)閉文件時(shí)都會刷新緩沖區(qū),進(jìn)行真正的I/O操作。

另外,我們可以使用 fflush 函數(shù)來刷新緩沖區(qū)(執(zhí)行I/O操作并清空緩沖區(qū))


接下來,我就來回答一下上述我們提出的幾個(gè)問題吧!

①不加換行符?\n時(shí)為何是先睡眠再打?。?/span>

  1. 對于上述的代碼而言,程序執(zhí)行時(shí)一定是順序執(zhí)行的,因此一定是先打印輸出語句中的內(nèi)容;
  2. 那么就有很多小伙伴好奇,我們怎么看不到這個(gè)現(xiàn)象呢?因?yàn)樗淮娣诺搅司彌_區(qū)里,由于sleep()函數(shù)的緣故,導(dǎo)致這個(gè)緩沖區(qū)沒有被刷新而已,所以它并沒有丟失

②加上\n后數(shù)據(jù)會立刻顯示出來,完成睡眠后才顯示提示符?

  1. 首先,我們需要知道一點(diǎn)。那就是無論我們加不加\n,數(shù)據(jù)都會被保存在緩沖區(qū)里。
  2. 因?yàn)檩敵龅淖詈笠粋€(gè)字符是 \n ,并且是往顯示器里面進(jìn)行打印,此外緩沖區(qū)還有很多的刷新策略。今天我們關(guān)心的是行緩沖,即->只要碰到了換行符,這就意味著此時(shí)就會把換行符之前的所有內(nèi)容全部顯示出來
  3. 所以字符串是以行緩沖的方式保存在了行緩沖區(qū)里,最后當(dāng)我們要退出的時(shí)候就會顯示出來,所以此時(shí)保存在沖區(qū)里的數(shù)據(jù)就會被刷新出來

③加上回車?\r后觀察不到我們輸出的數(shù)據(jù)。然而刷新一下就有了??

  1. 對于 \r 我們可以通過上述的輸出可以發(fā)現(xiàn),此時(shí)光標(biāo)會回到行首;
  2. 因?yàn)椋?dāng)我們打印的時(shí)候,當(dāng)遇到 \r 的時(shí)候,光標(biāo)就會回到最開始,但是這些數(shù)據(jù)并沒有在緩沖區(qū)中被移除,依舊是存在的;
  3. 當(dāng)我們 sleep() 的時(shí)候,光標(biāo)打印輸出的內(nèi)容時(shí)遇到 \r 就會回到最開始,但是程序執(zhí)行完之后,shell還會打印提示符,此時(shí)就會覆蓋掉程序輸出的內(nèi)容

(三)倒計(jì)時(shí)功能的實(shí)現(xiàn)

當(dāng)我們領(lǐng)悟到上述所講的知識之后,接下來我們先簡單的實(shí)現(xiàn)一個(gè)——倒計(jì)時(shí)。

1、9以內(nèi)的倒計(jì)時(shí)

  • 我們先來簡單的實(shí)現(xiàn)一下9以內(nèi)的倒計(jì)時(shí),思路很簡單,就是循環(huán)輸出即可。然后在打印完每個(gè)數(shù)字之后使用sleep(1)

代碼如下:

    1 #include<stdio.h>
    2 #include<unistd.h>
    3 int main()
    4 {
    5   int i=9;
    6   for(;i>=0; i--)
    7   {
    8     printf("%d\n",i);
    9     sleep(1);                                                                                                                                     
   10   }
   11  
   12   return 0 ;
   13 }

運(yùn)行結(jié)果如下:

上述就是最簡單的倒計(jì)時(shí)實(shí)現(xiàn)了。但是這跟我們想象的似乎不一樣啊是不是:

  • 我們希望看到的是在一行實(shí)現(xiàn)相應(yīng)的功能,并且每次輸出的結(jié)果把上次輸出的結(jié)果覆蓋掉,那么我們應(yīng)該怎么做呢?

接下來我就帶大家看看怎么實(shí)現(xiàn):

代碼如下:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   int i=9;
  6   for(;i>=0; i--)
  7   {
  8     printf("%d\r",i);  //注意這里變?yōu)榱薥r                                                                                                                                           
  9     fflush(stdout);
 10     sleep(1);
 11   }
 12 
 13   return 0 ;
 14 }

此時(shí)我們再去查看最終的結(jié)果:


2、10以內(nèi)的倒計(jì)時(shí)實(shí)現(xiàn)

不知道大家覺得【0-9】和【0-10】這二者實(shí)現(xiàn)倒計(jì)時(shí)是否一樣呢?其實(shí)是不一樣的喲?。?/strong>

  • 眼見為實(shí),我們把【i】的值改為10,看最終的結(jié)果是不是我們想要的那樣。

結(jié)論:

  • 通過上述我們不難發(fā)現(xiàn)一件事,當(dāng)是兩位數(shù)時(shí)只有前面的數(shù)字會被覆蓋,10后面的這個(gè)0會始終被保留下來,最后倒計(jì)時(shí)結(jié)束后便成了00

那么我們要如何修改才會和上述的一樣呢?

  • 在計(jì)算機(jī)打印時(shí),假設(shè)我們要打印的是【100】這個(gè)數(shù),那么是不是計(jì)算機(jī)就是按整數(shù)【100】的形式打印出來的呢?
  • 其實(shí)不是這樣的。在計(jì)算機(jī)打印中,它會把100 當(dāng)成三個(gè)字符進(jìn)行打印,即在計(jì)算機(jī)看來 100,就是由 字符 1 0 0 組成;
  • 將整型數(shù)字先轉(zhuǎn)換為字符串的形式,然后去遍歷這個(gè)字符串,用putc()這個(gè)函數(shù)將字符一一地打印在顯示器上

a)修改版

我們可以像如下一樣進(jìn)行修改,即可實(shí)現(xiàn)我們上述的效果。

代碼如下:

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 int main()
  4 {
  5   int i=10;
  6   for(;i>=0; i--)
  7   {
  8     printf("%2d\r",i);    //改為%2d                                                                                                                                          
  9     fflush(stdout);
 10     sleep(1);
 11   }
 12   return 0 ;
 13 }

運(yùn)行結(jié)果:

到此,在這里就簡單的實(shí)現(xiàn)出來了一個(gè)倒計(jì)時(shí)的“小玩具”。


(四)進(jìn)度條小程序(???)

有了以上的知識鋪墊,接下來就到了實(shí)現(xiàn) ——>進(jìn)度條小程序的實(shí)現(xiàn)過程了!

1、進(jìn)度條樣式說明

首先,就是給大家先說明一下本次進(jìn)度條我們最終呈現(xiàn)出來的樣式是什么樣的。

因?yàn)?,Linux下不是圖形化的,因此我們這里實(shí)現(xiàn)的進(jìn)度條就不是大家所熟知的網(wǎng)上看見的那種形狀。

首先,我先給出我們的進(jìn)度條的大概樣式,最后呈現(xiàn)出來的就是以下這種現(xiàn)象:

  • 【##################################>】【100%】【/】

說明:

1.主體部分大概就是用個(gè)【】來進(jìn)行概括,中間用 ## 這樣的符號來表示我們的進(jìn)度條的進(jìn)度樣式;

2.后一個(gè)【】則表示相應(yīng)的進(jìn)度情況;

3.因?yàn)槲覀兪窃贚inux環(huán)境下,無法做到這種圖形化界面。最后就是用旋轉(zhuǎn)字符的樣式來代替我們在 Windows下的緩沖的樣式


2、多文件實(shí)現(xiàn)

在這里我們給出的是多文件這樣的實(shí)現(xiàn)方案。因此在正式的上手之前,我們需要?jiǎng)?chuàng)建相應(yīng)的文件來表示相應(yīng)的代碼。

  • 【proc.h】:存放頭文件的文件夾
  • 【proc.c】:代表頭文件匹配的源文件,進(jìn)度條實(shí)現(xiàn)的邏輯存放在這里面
  • 【mainc】:來進(jìn)行程序的調(diào)度

先直接給出程序的大概框架,讓大家先見見:

【Linux】Linux第一個(gè)小程序-進(jìn)度條

  • ?接下來,我們要去編譯的話,此時(shí)我們還需要?jiǎng)?chuàng)建文件列表,即【makefile】來存放,這個(gè)在之前我們已經(jīng)詳細(xì)的講過了,這里就不多講了。直接給出,具體如下:

【Linux】Linux第一個(gè)小程序-進(jìn)度條

  • ?緊接著,我們邊去測試一下程序是否可以正常的編譯運(yùn)行:

【Linux】Linux第一個(gè)小程序-進(jìn)度條

?此時(shí),可能好多小伙伴就會有疑惑,在創(chuàng)建的文件列表【Makefile】中只有 main.c和 proc.c? 而沒有頭文件 proc.h 文件

  • 對于以上問題,之前在講解【gcc】的時(shí)候我大概提到過關(guān)于這個(gè)知識點(diǎn)。
  • 我們在進(jìn)行多文件編譯時(shí)候是不需要考慮【頭文件】的,因?yàn)樵陬A(yù)處理階段頭文件就會在它被包含的?.c源文件中進(jìn)行展開,因此加不加結(jié)果都是一樣的。
  • 一般我們是不加的

3、主體架構(gòu)實(shí)現(xiàn)

第一步:

#define SIZE 101

解釋說明:

  • 因?yàn)檫M(jìn)度條嘛!進(jìn)度就是從0到100 的,將整體進(jìn)度條看作是一個(gè)字符串,因此我們設(shè)置101來存放

第二步:

memset(bar, '\0', sizeof(bar));

解釋說明:

  1. 因?yàn)閷?shí)現(xiàn)這個(gè)進(jìn)度條推演就是一個(gè)循環(huán)的方式,每次都去修改這個(gè)字符數(shù)組當(dāng)前位置上的字符,將其變?yōu)?“=” ,緊接著去打印的時(shí)候下一個(gè)位置就會多出來一個(gè) “=” ,從而實(shí)現(xiàn)往后慢慢推進(jìn)的過程
  2. 初始化時(shí)就把數(shù)組全部的位置初始化為 \0 ,緊接著隨著進(jìn)度條的推進(jìn)去修改為 “=” 即可

代碼如下:

  1 #include"proc.h"
  2 
  3 #define SIZE 101
  4 
  5 void process()
  6 {
  7   char bar[SIZE];
  8 
  9   memset(bar,'\0',sizeof(bar));
 10 
 11   int i=0;
 12   while(i<+100)
 13   {
 14     printf("[%s]\n",bar);
 15     bar[i++]='#';                                                                                                                                                    
 16     sleep(1);
 17   }
 18 }
  • 此時(shí)我們編譯一下,看最終的結(jié)果是怎么樣的:

但是此時(shí)我們可以發(fā)現(xiàn),這是不斷的換行實(shí)現(xiàn)的,但是在我們的認(rèn)知中進(jìn)度條就是在 “一行 ”上實(shí)現(xiàn)的呀。因此,此時(shí)顯然不符合我們的預(yù)期

  1. 我們的預(yù)期是在一行上進(jìn)行不斷推進(jìn)的過程。因此,我們就不能加上【\n】這個(gè)字符;
  2. 我們使用【\r】,當(dāng)每次打印的時(shí)候,都從當(dāng)前行的起始位置處進(jìn)行操作。

當(dāng)我們完成上述要求之后,緊接著來編譯代碼看最終的結(jié)果是不是我們期望的那樣,具體如下:

  • 代碼如下:
  1 #include"proc.h"
  2 
  3 #define SIZE 101
  4 
  5 void process()
  6 {
  7   char bar[SIZE];
  8 
  9   memset(bar,'\0',sizeof(bar));
 10 
 11   int i=0;
 12   while(i<+100)
 13   {
 14     printf("[%s]\r",bar); //此時(shí)變?yōu)閈r                                                                                                                                           
 15     bar[i++]='#';
 16     sleep(1);
 17   }
 18 }
  • 運(yùn)行結(jié)果:

此時(shí),出現(xiàn)了一個(gè) “小坑” ,我們可以發(fā)現(xiàn)并沒有顯示出任何東西大家知道什么嗎?

  • 我相信聰明的小伙伴已經(jīng)知道了,即 緩沖區(qū)沒刷新!
fflush(stdout);
  • 再次運(yùn)行,結(jié)果如下:

不過此時(shí)有點(diǎn)小伙伴就會有這樣一個(gè)問題,是什么呢?

  • 我們可以觀察到這個(gè)進(jìn)度條推進(jìn)的速度很慢,那有沒有辦法讓它快一點(diǎn)呢?

答案是有的,此時(shí)有需要另外一個(gè)庫函數(shù)了,那就是 【usleep】函數(shù)。

  • 大家可以用 【man】手冊去查一下到底什么意思,我在這里給出簡略的回答:

【Linux】Linux第一個(gè)小程序-進(jìn)度條

  • ?代碼如下:
  1 #include"proc.h"
  2 
  3 #define SIZE 101
  4 #define ARP '>'
  5 
  6 void process()
  7 {
  8   char bar[SIZE];
  9 
 10   memset(bar,'\0',sizeof(bar));
 11 
 12   int i=0;
 13   while(i<+100)
 14   {
 15     printf("[%s]\r",bar);
 16     fflush(stdout);
 17     bar[i++]='#';
 18     usleep(100000);  //變?yōu)閡sleep                                                                                                                                                    
 19   }
 20 }
  • 運(yùn)行如下:

主體的進(jìn)度條預(yù)留出了一個(gè)100的空間,好呈現(xiàn)進(jìn)度條從0 ~ 100的推進(jìn),就可以上面說到過的格式化占位符

printf("[%100s]\r", bar);
  • 運(yùn)行結(jié)果:

我們可以發(fā)現(xiàn)怎么是從反方向走的,這也不是符合我們的需求??!

  • 別急,其實(shí)很好解決,只需在 輸出的 100前加上 【-】 即可實(shí)現(xiàn)從左開始輸出。
printf("[%-100s]\r", bar);
  • 運(yùn)行結(jié)果:

當(dāng)然我們還可以實(shí)現(xiàn)更多的樣式,例如假設(shè)我們要實(shí)現(xiàn)【===>】這樣的,我們可以怎么操作呢?

  • 代碼如下:
  1 #include"proc.h"
  2 
  3 #define SIZE 102    //記住,此時(shí)當(dāng)你加入的符號過多時(shí),空間也應(yīng)該隨之變大
  4 #define ARP '>'
  5 #define STYLE '='   //我們在這里用宏定義樣式,便于我們修改                                                                                                                                               
  6 
  7 void process()
  8 {
  9   char bar[SIZE];
 10 
 11   memset(bar,'\0',sizeof(bar));
 12 
 13   int i=0;
 14   while(i<+100)
 15   {
 16     printf("[%-100s]\r",bar);
 17     fflush(stdout);
 18     bar[i++]= STYLE;
 19     bar[i]=ARP;
 20 
 21     usleep(100000);
 22   }
 23 }
  • 運(yùn)行結(jié)果如下:

4、進(jìn)度的實(shí)現(xiàn)

實(shí)現(xiàn)完主體的框架之后,緊接著我們需要去實(shí)現(xiàn)一下百分比遞增

  • 代碼如下:
  1 #include"proc.h"  
  2   
  3 #define SIZE 102  
  4 #define ARP '>'  
  5 #define STYLE '='  
  6   
  7 void process()  
  8 {  
  9   char bar[SIZE];  
 10   
 11   memset(bar,'\0',sizeof(bar));  
 12   
 13   int i=0;  
 14   while(i<+100)  
 15   {  
 16     printf("[%-100s][%d]\r",bar,i);   //我們只需在最后加上輸出的值即可                                                                                                                           
 17     fflush(stdout);  
 18     bar[i++]= STYLE;  
 19     if(i != 100) bar[i]=ARP;  
 20   
 21     usleep(100000);  
 22   }  
 23 }  
  • 運(yùn)行如下:

但是此時(shí)我們可以發(fā)現(xiàn),輸出只是數(shù)字,并不是百分?jǐn)?shù)?。?

  • 我們只需在【%d】的后面在加上 % 即可,即——>【%d%%】
  • 結(jié)果如下:

到此,關(guān)于進(jìn)度的實(shí)現(xiàn)便完成了。接下來就是關(guān)于緩沖功能了?。?!


5、緩沖功能的實(shí)現(xiàn)

終于到了最后。馬上就要揭開我們進(jìn)度條的了 ”廬山真面目“了。

  • 此時(shí)我們只需要定義一個(gè)字符數(shù)組,并用【const】來修飾。
  • 目的很簡單就是防止里面的內(nèi)容被修改。
const char* label = "|/-\\";
  • 最后在打印的時(shí)候,要去實(shí)現(xiàn)一個(gè)輪回就需要用到一個(gè)取余操作,每次打印的都是【0 ~ 3】的倍數(shù),因此模上4 即可
printf("[%-100s][%d%%][%c]\r", bar, i , label[i % 4]);

運(yùn)行如下:

到此,我們就實(shí)現(xiàn)了一個(gè)進(jìn)度條小程序的設(shè)計(jì)。最終代碼如下:

  1 #include"proc.h"
  2 
  3 #define SIZE 102
  4 #define ARP '>'
  5 #define STYLE '='
  6 
  7 void process()
  8 {
  9   const char* label = "|/-\\";
 10   char bar[SIZE];
 11 
 12   memset(bar,'\0',sizeof(bar));
 13 
 14   int i=0;
 15   while(i<+100)
 16   {
 17     printf("[%-100s][%d%%][%c]\r", bar, i , label[i % 4]);                                                                                                           
 18     fflush(stdout);
 19     bar[i++]= STYLE;
 20     if(i != 100 )bar[i]=ARP;
 21 
 22     usleep(100000);
 23   }
 24 }

(五)總結(jié)

到此,關(guān)于進(jìn)度條小程序的所有知識便講解完畢了!接下來,我們一起回顧一下

  • 首先我們學(xué)習(xí)了C語言中的兩個(gè)控制字符【\n】與【\r】,知道了這兩者的作用及功能;
  • 緊接著我們又引出了緩沖區(qū)的概念,并且通過代碼的形式給大家具體的呈現(xiàn)了出來。知道了緩沖區(qū)是需要被刷新才會被顯示出來的;
  • 有了以上知識點(diǎn)的鋪墊,我們通過設(shè)計(jì)的倒計(jì)時(shí)的功能給大家變相的總結(jié)了上文,并且對上述知識進(jìn)行了運(yùn)用;
  • 最后,就是總結(jié)上文,之前的一切都是在給我們即將設(shè)計(jì)的 進(jìn)度條小程序做“背景板”。通過幾個(gè)方面的講述帶領(lǐng)大家對這個(gè)小程序進(jìn)行了實(shí)現(xiàn)。

以上就是本文的所有知識,感謝各位的支持?。?!

【Linux】Linux第一個(gè)小程序-進(jìn)度條

?文章來源地址http://www.zghlxwxcb.cn/news/detail-429713.html

到了這里,關(guān)于【Linux】Linux第一個(gè)小程序-進(jìn)度條的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Linux】編寫第一個(gè)小程序:進(jìn)度條

    【Linux】編寫第一個(gè)小程序:進(jìn)度條

    1.1.1 sleep() 作用:讓程序休眠指定秒數(shù),如: sleep(3); //讓程序休眠3秒 與 Windows 上的 Sleep() 函數(shù)不同 需要包含頭文件 unistd.h 1.1.2 fflush() 作用:刷新緩沖區(qū) 需要傳入一個(gè)流 需要包含頭文件 stdio.h 1.1.3 usleep() 作用:讓程序休眠指定微秒,如: usleep(100000); //讓程序休眠100000微秒(

    2024年02月02日
    瀏覽(22)
  • linux第一個(gè)小程序 --- 進(jìn)度條【簡潔】

    linux第一個(gè)小程序 --- 進(jìn)度條【簡潔】

    結(jié)果:先輸入hello world然后休眠三秒后結(jié)束 當(dāng)去掉’\\\'n“ 后,結(jié)果就變成了先休眠三秒,然后打印hello world后結(jié)束。 該現(xiàn)象就證明了緩沖區(qū)的存在。 當(dāng)緩沖區(qū)中遇到’‘n’\\\'或者緩沖區(qū)被寫滿后才會被打印出來,在第二張圖片里面,沒有n,所以hello world先被寫入緩存區(qū),然后

    2024年01月20日
    瀏覽(18)
  • 【Linux系統(tǒng)編程】Linux第一個(gè)小程序——進(jìn)度條

    【Linux系統(tǒng)編程】Linux第一個(gè)小程序——進(jìn)度條

    這篇文章我們一起來完成我們Linux中的第一個(gè)小程序——進(jìn)度條 在C語言中,字符可以分為可顯字符(printable characters)和控制字符(control characters)。 可顯字符是指可以在屏幕或打印輸出上顯示的字符,它們包括數(shù)字、字母、標(biāo)點(diǎn)符號、符號等??娠@字符可以直接被用戶看到

    2024年02月16日
    瀏覽(23)
  • Linux第一個(gè)小程序-進(jìn)度條(c語言版)

    Linux第一個(gè)小程序-進(jìn)度條(c語言版)

    目錄 行緩沖區(qū)概念: 行緩沖區(qū)代碼演示: ?編輯進(jìn)度條代碼 1:memset函數(shù): 2:const char* lable=\\\"|/-\\\\\\\";? 3:usleep C語言?usleep?函數(shù)的功能和用法: 4:進(jìn)度條代碼的實(shí)現(xiàn).c文件與.h文件: ?編輯?編輯5:運(yùn)行截圖 ?編輯進(jìn)度條代碼的實(shí)用性優(yōu)化 優(yōu)化1:processbar函數(shù)內(nèi)部循環(huán)改為

    2024年01月15日
    瀏覽(19)
  • 【Linux】從0到1實(shí)現(xiàn)一個(gè)進(jìn)度條小程序

    【Linux】從0到1實(shí)現(xiàn)一個(gè)進(jìn)度條小程序

    個(gè)人主頁:??在肯德基吃麻辣燙 我的gitee:gitee倉庫 分享一句喜歡的話:熱烈的火焰,冰封在最沉默的火山深處 進(jìn)度條實(shí)現(xiàn): 本文講解如何從0到1實(shí)現(xiàn)一個(gè)進(jìn)度條小程序。 我們在寫作文的時(shí)候,寫到了一行的結(jié)尾,就得另起一行并到開頭繼續(xù)寫。 其中,這個(gè)另起一行的動作

    2024年02月14日
    瀏覽(27)
  • 《Linux從練氣到飛升》No.07 Linux第一個(gè)小程序-進(jìn)度條的實(shí)現(xiàn)

    《Linux從練氣到飛升》No.07 Linux第一個(gè)小程序-進(jìn)度條的實(shí)現(xiàn)

    ??作者: 主頁 我的專欄 C語言從0到1 探秘C++ 數(shù)據(jù)結(jié)構(gòu)從0到1 探秘Linux 菜鳥刷題集 ??歡迎關(guān)注:??點(diǎn)贊??收藏??留言 ?? 碼字不易,你的??點(diǎn)贊??收藏??關(guān)注對我真的很重要,有問題可在評論區(qū)提出,感謝閱讀?。?! 前面幾章我們講述了Linux指令、權(quán)限管理、編輯器

    2024年02月14日
    瀏覽(31)
  • 【Linux】:使用git命令行 || 在github創(chuàng)建項(xiàng)目 || Linux第一個(gè)小程序——進(jìn)度條(進(jìn)階版本)

    【Linux】:使用git命令行 || 在github創(chuàng)建項(xiàng)目 || Linux第一個(gè)小程序——進(jìn)度條(進(jìn)階版本)

    在本章開始之前還是先給大家分享一張圖片 這是C++的筆試題 感興趣的同學(xué)可以去試一試 有難度的喲 也可以直接在??途W(wǎng)直接搜索這幾道題目哈 好了今天我們正式進(jìn)入我們的正題部分 安裝git 使用 Github 創(chuàng)建項(xiàng)目 注冊賬號 創(chuàng)建項(xiàng)目 ??1. 登陸成功后, 進(jìn)入個(gè)人主頁, 點(diǎn)擊左下

    2024年02月05日
    瀏覽(23)
  • 【Linux】:Linux項(xiàng)目自動化構(gòu)建工具——make/Makefile || Linux第一個(gè)小程序——進(jìn)度條(簡單版本)

    【Linux】:Linux項(xiàng)目自動化構(gòu)建工具——make/Makefile || Linux第一個(gè)小程序——進(jìn)度條(簡單版本)

    在本章開始給大家分享一個(gè)圖片 希望對你有幫助 在這里插入圖片描述 在開始本章之前 我們需要回顧一下上節(jié)課的函數(shù)的動靜態(tài)庫的優(yōu)缺點(diǎn) 動態(tài)庫的優(yōu)點(diǎn): 比較節(jié)省資源(這里說的資源不僅僅是磁盤資源 也包括網(wǎng)絡(luò)資源 內(nèi)存資源等等),不會出現(xiàn)太多的重復(fù)代碼 缺點(diǎn):對

    2024年02月05日
    瀏覽(40)
  • shell 編寫一個(gè)帶有進(jìn)度條的程序安裝腳本

    shell 編寫一個(gè)帶有進(jìn)度條的程序安裝腳本

    使用 shell 寫一個(gè) 軟件安裝腳本,帶有進(jìn)度條 在這個(gè)示例中,使用 ANSI 轉(zhuǎn)義序列來實(shí)現(xiàn)覆蓋原來的打印信息,并保持進(jìn)度條在同一行顯示。通過使用 r 進(jìn)行回車,然后使用 \\033[K 清除當(dāng)前行的內(nèi)容,可以實(shí)現(xiàn)覆蓋效果。 在 print_progress 函數(shù)中,首先清除當(dāng)前行的內(nèi)容,然后構(gòu)

    2024年02月11日
    瀏覽(25)
  • 【Linux】Linux小程序-進(jìn)度條

    【Linux】Linux小程序-進(jìn)度條

    目錄 ????????一、r和n的理解 ????????二、行緩沖區(qū)概念 ????????三、進(jìn)度條源代碼 r:回車; n:換行; ? ? 那么請問這兩個(gè)有什么區(qū)別呢? ? ? 比如:我們在編寫內(nèi)容的時(shí)候,一行沒有寫完的情況下,需要換到下一行的開始位置,此時(shí)需要兩個(gè)步驟: ? ?

    2024年02月06日
    瀏覽(18)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包