用15行C语言实现一个进度条(底层原理大刨析 你学会的不只是进度条代码实现本身 包看包会)

目录

0. 前言注意

1.刷新策略

2.打印实质

2.1 屏幕打印

 2.2 回车换行\r\n

3.进度条代码


0. 前言注意

话不多说我们先上这15行代码

#include<stdio.h>
#include<unistd.h>
int main(){
#define NUM 100
  char buffer[NUM+1] = {0};//存储进度条字符
  char arr[5] = {"-/|\\"};//存储基本的变化字幕
  for(int i = 0;i<NUM ;++i){
    buffer[i] = '#';
    printf("[%-100s][%d%%][%c]\r",buffer,i+1,arr[i%4]);
    fflush(stdout);
    usleep(60000);
  }
  printf("\n");
  return 0;
}

博主的Gitee码云中也存有15行进度条代码(此外还有更多宝藏代码) , 需要的同学可以自取~

practice4 · onlookerzy123456qwq/Linuxtwo - 码云 - 开源中国 (gitee.com)icon-default.png?t=M85Bhttps://gitee.com/onlookerzy123456qwq/linuxtwo/tree/master/practice4

本文将会结合生动形象的例子首先对 行刷新测量 以及 屏幕打印的实质 这两大原理进行讲述 , 再进行进度条代码的书写 , 让你学到的不只是进度条代码本身。

1.刷新策略

我们首先看一个惊奇的现象 , 先休眠 , 再打印到屏幕上 , 难道printf真的执行的比sleep慢吗?

当然不可能!!!

这个就涉及到printf的封装 , 我们的printf实际上是对系统调用接口的封装 , printf并不直接打印到屏幕上 , printf函数打印到的地方不是屏幕 ! 而是打印到一个C的用户缓冲区中 !

更具体的说 , printf打印的内容是不会直接刷新到屏幕上的 , printf作为一个C的接口函数 , 其打印的内容会首先刷新到C语言用户级别的缓冲区 , 然后再刷新到系统级别的缓冲区最后刷新到屏幕上 。 其中最致命的点就在于 C语言用户级别的缓冲区的内容 什么时候 刷新到系统缓冲区进而到屏幕当中。什么时候刷新用户级缓冲区就涉及到缓冲区的刷新策略问题!

 

何时刷新 : 

C语言用户缓冲区的刷新策略是 行刷新策略 , 也就是说 , 之后在用户缓冲区中出现了 \n 行号时 , 才会将现在缓冲区的内容都刷新到 系统缓冲区 进而刷新到屏幕

或者只有当整个程序退出的时候 , 才会将用户级缓冲区内的内容全部刷新出来。

举个例子 : 

 

事实上 , printf是对系统调用接口打印的封装 , 只有系统调用接口是直接和系统缓冲区打交道 , 而printf接口是对系统接口的封装 , 所以用户级缓冲区&&用户级缓冲区的行刷新策略是printf这种做封装后的函数所特有的东西。

 

总结 : 

其实你只需要记住 1. printf的实质是把print的内容写入到C语言用户缓冲区中。

2. C用户缓冲区的刷新策略是遇到\n换行才会将C用户缓冲区的内容刷新出去到屏幕。

认识了printf的实质以及C用户缓冲区的行刷新策略 , 我们再认识一下fflush接口 , 可以强制把我们的C用户级缓冲区的内容进行直接到屏幕的刷新。(可以不拘泥于有\n才能进行刷新)

 

2.打印实质

2.1 屏幕打印

 屏幕上可以看作分成了一个一个的小格子 , 打印的实质就是在屏幕上覆盖这些小格子 , 然后用户就能看到屏幕上覆盖的字符图案了。

 2.2 回车换行\r\n

换行\n , 精确的说是定位到下一行的行首。 

回车\r , 精确的说是定位到当前的行首。

 示例 : 

printf("abc\r");

fflush(stdout);

printf("ef");

这三行代码的执行就是先覆盖打印 abc , 再定位从该行的行首开始打印覆盖 。

将abc\r打印出去之后 , 我们再打印ef就会覆盖后面的字符 , 也就是说现在显示的就是ef。 

 

3.进度条代码

进度条思路的构建 : 

进度条实际上就是在屏幕的同一行中 , 在短时间间隔中不间断回到首行并覆盖打印越来越多的字符 , 例如我先打印一个# , 在0.01s后\r回到该行首行 , 再从行首位置向后覆盖打印两个## , 0.01s后再\r回到该行的首行 , 再打印三个###进行该行的覆盖打印 ....... 如此不间断的  进入首行+往后覆盖打印  , 就可以实现进度条的显现。

 

 

  • 15
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值