当前位置: 首页 > news >正文

linux进度条程序

文章目录

  • linux进度条程序
    • 两个背景知识
    • 倒计时功能
    • 进度条程序
    • 结语

很高兴和大家见面,给生活加点impetus!!开启今天的编程之路
在这里插入图片描述
今天我们来学习Linux的基础构建工具,主要从是什么为什么,怎么做的角度出发,包含细节,示例
作者:٩( ‘ω’ )و260
我的专栏:Linux,C++进阶,C++初阶,数据结构初阶,题海探骊,c语言
欢迎点赞,关注!!

linux进度条程序

两个背景知识

结论1:回车换行是两个动作

平常我们写作文的时候,当我们要在下一行书写内容的时候,我们需要换行,同时,需要回车到下一行的开始。这点不多说,应该都能够理解~
所以,回车的转义字符的方式为\r,换行的转义字符的方式为\n,只不过\n其中内置了回车效果

这里我们使用两个例子来输出结论2,我们首先来看两段代码:
在这里插入图片描述
c语言的基本常识就为顺序结构,代码执行肯定是从上到下,此时肯定是打印了,那么打印的结果跑到哪里去了呢?
这里我也不卖关子了,这里结果其实已经是打印了,但是打印到缓冲区当中了,同时,这个缓冲区也有归属,归属于显示器。
为什么最后结果打印了呢?
答案是:归属于显示器的缓冲区其中的内容想要打印到显示器上,缓冲区必须要进行行刷新,而\n刚好就有换行的作用,所以就直接刷新到了显示器上,同时当程序运行结束的时候,显示器也会刷新。自动将其中的内容打印出来

提取结论:

缓冲区刷新方式,按照行为单位进行刷新\r\n或者\n
程序运行结束,缓冲区里的内容会被自动刷新

这里我们可以联想一个函数:IO流中的cout,作用是换行和刷新字符缓冲区,所以一定能够将缓冲区的内容打印出来~

倒计时功能

我们来完成一个代码来验证上面的结论,同时,我们也能够学到新的函数。
首先我们先来分析特点,首先因为是倒计时,而且肯定是在一个位置倒计时。我们先来看代码:
在这里插入图片描述
倒计时应该是在一个位置一直到0,这里的错误之处是换行了,当我们把换行去掉,再来看结果:
在这里插入图片描述
这个是什么原因呢?还是跟上面的结果是一样的,此时打印的结果在缓冲区中,此时缓冲区没有刷新,自然结果也就不会打印到显示屏上。

有一个函数fflush能够刷新缓存区,需要传递一个文件信息参数,在linux下,一切皆文件,当然,显示屏也是有文件的,可以理解为就是stdout:
在这里插入图片描述
所以我们传参就传stdout就行:
在这里插入图片描述
接下来我们来重新书写代码:
在这里插入图片描述
是不是应该8应该要替换掉9的位置,7应该要替换掉8的位置~
此时我们应该要回车,这样就能够到达这一行的开始~
在这里插入图片描述
所以,这里我们需要fflush和回车(\r)同时配合使用~

这里我们再来讲解一个知识点,我们来看,如果我们数字从10开始相减呢呢?
在这里插入图片描述
我们发现一个奇怪的现象,我们发现10后面的0没有给替换掉,只是将1给替换掉了,这里我们可以提出问题:为什么会是替换的结果?

这里我们需要提到格式化输出,格式化输入,格式化的到底是什么?
其实显示器是字符块设备,即显示器上输出的东西其实都是字符,即使我们定义了整形,但是我们其实输入的输出的都是字符,但是,保存在内存中的就是整形,所以格式化输入输出在这里的作用就是依靠ascll码进行整形和字符的转换,其余也是同理的~

在倒计时程序中,10其实是1和0字符,替换的话只是替换了1字符,0字符还保留的。所以我们这里替换两个字符,所以应该使用%2d即可:
同时,%2d默认方式是右对齐,即有字符的话在右边替换掉,左边使用空格替换,但是这里我们需要左对齐,来看代码及结果:
在这里插入图片描述
这样我们一个简单的倒计时程序就书写完毕,接下来我们来书写进度条程序:

进度条程序

首先进度条程序需要什么,首先,我们肯定需要进度,百分比,以及旋转轮盘,因为有了旋转轮盘,我们才能够知道这个进度条程序还在运转没有!!
我们直接来看代码:
在这里插入图片描述
因为有100个百分点,所以我使用100个位置,当有了一个百分点之后,同时就会输出一个等号。
为什么这里我使用’\0’来初始化processbuff数组呢?因为printf函数遇到’\0’会停止打印了。这里的usleep其实和sleep一样的,都是睡眠,差别就是usleep的参数是传递的微秒,来看结果
在这里插入图片描述
但是,这种进度条有没有什么实际的开发场景呢?比如说,我下载游戏,下载的过程中可以使用进度条来表明还有多久下载成功了,但是上面的代码肯定是不能代表这种场景的。

在实际下载场景中,涉及网络波动,所以进度条肯定会时快时慢,而且还应该有下载的大小,而且当网速为0或者很慢,但是仍在下载,轮盘也应该转动。此时我们直接来书写代码:

//main.c
#include"process.h"                                                                                                                                                  
double gtotal = 1024.0;//1024M                                                                                    
double speed = 1.0;//设置浮动区间使用种子函数                                                                                     double speedFloat(double speed,double range)//[1,0,5.3]                                                           
{                                                                                                                                                            int int_range = (int)range;                                                                                      return speed + rand()%int_range + (range - int_range);//记得加上小数部分                                                                        
}                                                                                                                             void DownLoad(int total,callback_t cd)                                                                                                  {                                                                                                                                          srand(time(NULL));                                                                                                                                             double curr = 0;                                                                                                while(curr <= total)                                                                                                        {                                                                                                                                                            curr += speedFloat(speed,20.3);                                                                               cd(curr,total);//这里千万不能传引用,否则会造成死循环                                                                                              usleep(30000);                                                                                                                          }                                                                                                                                                               }                                                                                                                                                        int main()                                                                                                                         {                                                                                                                                DownLoad(gtotal,FlushProcess);                                                                                                                   //process();                                                                                                    return 0;                                                                                                       }  

main.c我们使用种子函数,这样就能够生成随机数,来实现网速快慢的情况,进而模式网络波动~

而且,这里我们使用函数指针来封装进度条程序,这样能够使得更加便捷,即我们只用修改上层传入的函数,下层我们什么都不用管了。

定义格式:
typedef 返回类型(*新类型名)(参数类型)

//process.h
#pragma once                                                                    #include<stdio.h>                                                                                                                 #include<unistd.h>                                                                                                                 #include<string.h>                                                                                                                          #include<time.h>                                                                                                                                             #include<stdlib.h>                                                                                                 typedef void (*callback_t)(double,double);                                                                                                                           void DownLoad(int total,callback_t cd);                                                                                                    void process();                                                                                                                                                  void FlushProcess(double curr,double total);    

这里是头文件,进行声明,其中unistd.h头文件含义是unix标准,因为linux是由unix演变而来的,所以肯定会涉及一定的unix

//process.c#include"process.h"#define SIZE 101#define STYLE '='void FlushProcess(double curr,double total){if(curr > total) curr = total;//计算比率double rate = curr / total * 100;int cnt = (int)rate;char processbuff[SIZE];memset(processbuff,'\0',sizeof(processbuff));int i = 0;for(; i < cnt; i++) processbuff[i] = STYLE;static const char* label = "|/-\\";int len = strlen(label);static int index = 0;//用来标记label数组的位置printf("[%-100s][%.1lf%%][%c]\r",processbuff,rate,label[index++]);fflush(stdout);index %= len;if(curr >= total) printf("\n");}

这里是核心操作,其实细节跟我们上面讲的倒计时程序细节雷同,无非就是多了保留小数点后一位

结语

感谢大家的阅读,不足之处欢迎留言指正,感谢大家支持!!
博观而约取,厚积而薄发!!
在这里插入图片描述

http://www.xdnf.cn/news/1231723.html

相关文章:

  • WD5208S,12V500MA,应用于小家电电源工业控制领域
  • Z20K118库中寄存器及其库函数封装-WDOG库
  • 深入 Go 底层原理(十):defer 的实现与性能开销
  • hcip---ospf知识点总结及实验配置
  • 淘宝获取商品SKU详情API接口操作指南
  • Python爬虫实战:研究SimpleCV技术,构建图像获取及处理系统
  • 注意点:不同对象(更准确地说,不同类型/类)的魔法方法(Magic Methods,也叫特殊方法,以双下划线`__`开头和结尾)通常是不一样的。
  • 字节Seed发布扩散语言模型,推理速度达2146 tokens/s,比同规模自回归快5.4倍
  • 深入 Go 底层原理(三):Goroutine 的调度策略
  • [论文阅读] 人工智能 + 软件工程 | GitHub Marketplace中CI Actions的功能冗余与演化规律研究
  • Text2SQL:如何通过自然语言直接获取数据,打破技术壁垒?
  • 【Android】通知
  • Docker 的网络模式
  • 红黑树(RBTree)
  • 【LeetCode 热题 100】(四)子串
  • 前端-移动Web-day3
  • 云环境K8s集群WebSocket连接失败解决方案
  • 【REACT18.x】使用vite创建的项目无法启动,报错TypeError: crypto.hash is not a function解决方法
  • 基于 LightGBM 的二手车价格预测
  • GaussDB having 的用法
  • 图像加密学习日志————论文学习DAY4
  • 分布式事务----spring操作多个数据库,事务以及事务回滚还有用吗
  • 机械臂的轨迹生成的多种方案
  • Jupyter notebook如何显示行号?
  • MFC 实现托盘图标菜单图标功能
  • NCV8402ASTT1G自保护N沟道功率MOSFET安森美/ONSEMI 过流过温保护汽车级驱动NCV8402ASTT1
  • 从基础功能到自主决策, Agent 开发进阶路怎么走?
  • 【计算机网络】Socket网络编程
  • Android 15 限制APK包手动安装但不限制自升级的实现方案
  • 断路器瞬时跳闸曲线数据获取方式