Linux第一个小程序进度条

news/2024/7/20 3:23:29 标签: 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<stdio.h>    
#include<unistd.h>    
#include<string.h>    

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版本是外观美化

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


http://www.niftyadmin.cn/n/5153917.html

相关文章

Python基础入门例程47-NP47 牛牛的绩点(条件语句)

最近的博文&#xff1a; Python基础入门例程46-NP46 菜品的价格&#xff08;条件语句&#xff09;-CSDN博客 Python基础入门例程45-NP45 禁止重复注册&#xff08;条件语句&#xff09;-CSDN博客 Python基础入门例程44-NP44 判断列表是否为空&#xff08;条件语句&#xff0…

【unity实战】Unity实现2D人物双击疾跑

最终效果 前言 我们要实现的功能是双击疾跑&#xff0c;当玩家快速地按下同一个移动键两次时能进入跑步状态 我假设快速按下的定义为0.2秒内&#xff0c;按下同一按键两次 简单的分析一下需求&#xff0c;实现它的关键在于获得按键按下的时间&#xff0c;我们需要知道第一次…

python 命令行界面的用户交互

背景 说一千&#xff0c;道一万&#xff0c;程序是为用户服务的&#xff0c;所以在程序运行过程&#xff0c;与用户交互以获取用户的信息输入和决策确认&#xff0c;是无法避免的编程需要考虑和解决的需求。 一个简单的demo 如下的程序中&#xff0c;程序需要生成一个新的 i…

Qt OpenGL相机系统

文章目录 一、简介二、实现代码三、实现效果参考资料效果展示 一、简介 一直偷懒没有学习OpenGL,乘着这段有点时间重新学习一下OpenGL,做一个简单的小工具,有助于后面理解OSG。我们都知道OpenGL中存在着下面几个坐标空间:模型空间(物体空间)、世界空间、观察空间(或者称…

差生文具多之(一)eBPF

前言 在问题排查过程中, 通常包含: 整体观测, 数据采集, 数据分析这几个阶段. 对于简单问题的排查, 可以跳过前两个步骤, 无需额外收集数据, 直接通过分析日志中的关键信息就可以定位根因; 而对于复杂问题的排查, 为了对应用的行为有更完整的了解, 可以通过以下形式收集更多的…

树状数组(分析+代码)

在2023年4月29日的力扣103夜喵双周赛上&#xff0c;我被第四题所困扰&#xff0c;又于2023年5月4日早上的Linux系统基础课上&#xff0c;我初次接触到了树状数组。从那时候我就想写一篇博客记录一下&#xff0c;鸽到了现在… 参考视频 树状数组的作用 维护一个序列修改某一个…

【移远QuecPython】EC800M物联网开发板的硬件PWM和PWM输出BUG

【移远QuecPython】EC800M物联网开发板的硬件PWM和PWM输出BUG 文章目录 导入库初始化PWM开启PWMPWM硬件BUG附录&#xff1a;列表的赋值类型和py打包列表赋值BUG复现代码改进优化总结 py打包 导入库 from misc import PWM_V2或者 from misc import PWM但我觉得PWM_V2好用 初…

【GEE】​3、 栅格遥感影像波段特征及渲染可视化

1、简介 在本单元中&#xff0c;将学习以下内容&#xff1a; 使用遥感传感器捕获的不同类型的能量。如何构建 JavaScript 字典和列表以选择单个栅格波段。如何可视化多波段和单波段栅格的不同组合。 2、背景 在您探索如何将 Google 地球引擎和遥感数据集成到您的研究中时&…