Linux第一个小程序进度条

缓冲区

​ 在写进度条程序之前我们需要介绍一下缓冲区,缓冲区有两种,输入和输出缓冲区,这里主要介绍输出缓冲区。在我们用C语言写代码时,输出一些信息,实际上是先输出到输出缓冲区里,然后才输出到我们的显示器上。
原因是:

如果输出一个字符就打印到显示器上,那么就会有大量的IO交流在显示器上,外设的速度比较慢,这会降低系统效率,所以就有缓冲区减少IO次数,等我们手动或者达到一定条件(进程结束)时缓冲区刷新就会打印信息到显示器上

看下面两段代码:

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

这段代码先等待2秒然后才输出123,因为printf先输出123到缓冲区中,等2秒后程序结束刷新缓冲区就把信息打印到显示器上

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

这段代码是先打印123,然后等2秒程序结束,\n能手动刷新缓冲区,所以是先打印123然后等2秒程序结束


\n&&\r

\r是回车,就是光标回到当前行第一位,\n是换行,就是光标移动到当前位置下一行。我们键盘上的Enter是换行加回车一起进行的。

进度条的实现

​ 实现进度条之前我们先写好我们的makefile文件:

myexe:test.c process.c                                                                                    
  @gcc -o $@ $^    
.PHONY:clean    
clean:    
  @rm -f myexe    

version1

v1版本就是一个普通进度条,只有样式

process.h

  1 #pragma once             
  2 #include<stdio.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 
  6 void process(); //声明函数

process.c

  1 #include"process.h"                
  2 
  3 #define SIZE 100
  4 #define SLEEPTIME 1000*50
  5 #define STYLE '#'
  6 
  7 char str[SIZE+1]={0};
  8 char wait[]={"|/-"};
  9 
 10 void process()
 11 {
 12   int rate = 0, wsize = strlen(wait);
 13   while(rate <= SIZE)
 14   {
 15     printf("[%-100s][%d%%][%c]\r",str,rate,wait[rate%wsize]); //输出格式
 16     fflush(stdout); //刷新缓冲区
 17     usleep(SLEEPTIME); //等待
 18     str[rate++] = STYLE; //增加'#'
 19   }
 20   printf("\n");
 21 }

test.c

  1 #include"process.h"
  2 
  3 int main()
  4 {
  5   process(); //调用函数              
  6   return 0;
  7 }

image-20231105163644079


version2

v2版本的进度条根据实际情况进行变化的,符合实际

process.h

#pragma once    
#include    
#include    
#include    

typedef void (*callback_t)(int); //重定义函数指针                                      

void process_v2(int rate);    

process.c

#include"process.h"    

#define SIZE 100    
#define STYLE '#'    

char str[SIZE+1]={0};    
char wait[]={"|/-\\"};  
int cnt = 0;

void process_v2(int rate)    
{    
  cnt++; //当进度卡住时,指示标还会一直转动,表示正在下载
  int size = strlen(str);    
  while(size < rate) //判断当前进度条的符号数量是否符合传进来的进度   
    str[size++] = STYLE;    
  if(rate >= 0 && rate <= SIZE)    //判断rate合法性
  {    
    int wsize = strlen(wait);    
    printf("[%-100s][%d%%][%c]\r",str,rate,wait[cnt%wsize]);    
    fflush(stdout);    
  }                                                                                                       
}  

test.c

#include"process.h"    

#define TARGET 1024*1024    
#define DOWNLOAD 5000

void download(callback_t cb)    
{    
  int cur = 0;    
  while(1)    
  {    
    cur += DOWNLOAD; //下载ing   
    int rate = (cur*100)/(TARGET); //计算当前进度   
    if(rate > 100)  //判断rate是否合法
      rate = 100;    
    cb(rate);  //回调函数 
    if(rate >= 100) //如果进度已经打到100就退出   
      break;    
    usleep(10000); //模拟下载等待时间    
  }    
  printf("\n");    
}    

int main()    
{    
  download(process_v2);    

  return 0;    
}    

image-20231105214019715


version3

v3版本是外观美化

可以对格式进行更改,加点文字描述,以及更改颜色和底色,详情百度,这里就不再赘述

你可能感兴趣的:(linux,小程序,运维)