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

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

相关推荐
Johny_Zhao1 小时前
OpenClaw安装部署教程
linux·人工智能·ai·云计算·系统运维·openclaw
chlk1232 天前
Linux文件权限完全图解:读懂 ls -l 和 chmod 755 背后的秘密
linux·操作系统
舒一笑2 天前
Ubuntu系统安装CodeX出现问题
linux·后端
改一下配置文件2 天前
Ubuntu24.04安装NVIDIA驱动完整指南(含Secure Boot解决方案)
linux
碳基沙盒2 天前
OpenClaw 多 Agent 配置实战指南
运维
深紫色的三北六号2 天前
Linux 服务器磁盘扩容与目录迁移:rsync + bind mount 实现服务无感迁移(无需修改配置)
linux·扩容·服务迁移
SudosuBash2 天前
[CS:APP 3e] 关于对 第 12 章 读/写者的一点思考和题解 (作业 12.19,12.20,12.21)
linux·并发·操作系统(os)
哈基咪怎么可能是AI3 天前
为什么我就想要「线性历史 + Signed Commits」GitHub 却把我当猴耍 🤬🎙️
linux·github
十日十行3 天前
Linux和window共享文件夹
linux
木心月转码ing4 天前
WSL+Cpp开发环境配置
linux