Linux第一个小程序进度条

缓冲区

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

原因是:

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

看下面两段代码:

c 复制代码
  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秒后程序结束刷新缓冲区就把信息打印到显示器上

c 复制代码
  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

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

process.c

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

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

version2

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

process.h

c 复制代码
#pragma once    
#include<stdio.h>    
#include<unistd.h>    
#include<string.h>    

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

void process_v2(int rate);    

process.c

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

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;    
}    

version3

v3版本是外观美化

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

相关推荐
qq_316411037 小时前
商用冷柜售后报修运维管理系统开发案例
运维
智码看视界7 小时前
Day59-阿里云ACK实战:生产级K8s集群部署与运维
运维·阿里云·kubernetes·k8s·日志监控·容器运维·阿里云ack
ltl8 小时前
QUIC 握手实现:Initial 到 1-RTT 的最小路径
linux
码视野9 小时前
基于 Vue3 + Element Plus 的【智慧新能源汽车充电桩运维调度与分时共享租赁系统】设计与实现(附完整源码与PRD)
运维·人工智能·汽车·vue3
qq_426003969 小时前
【UI自动化测试】UI自动化报错解决方案
运维·ui·自动化
网安蟹佬霸9 小时前
WAF绕过技术实战:从规则检测到编码绕过全指南(2026最新版,附Payload集与自动化脚本)
运维·安全·网络安全·架构·自动化·网安
小杨不想秃头9 小时前
信息安全工程师教程第二章密码学
运维·服务器·密码学
I'mChloe9 小时前
WGCLOUD怎么监控多台服务器?从Server、Agent 部署到监控面板实战
运维·服务器
Android系统攻城狮10 小时前
Linux PipeWire深度解析之pw_init调用流程与实战(八十三)
linux·运维·服务器·音频进阶·pipewire音频进阶
国科安芯10 小时前
轨道供电韧性:ASP4644四通道降压架构在低轨卫星平台电源管理中的适用性分析
运维·网络·数据库·嵌入式硬件·架构·状态模式·低轨卫星星座