Linux 进度条

news2024/11/28 22:52:24

文章目录

  • 一、理解回车换行
  • 二、认识行缓冲
    • 1、代码一、二(回车换行理解)
    • 2、代码三、四(sleep函数和ffush函数理解)
  • 三、简单倒计时
    • 1、效果展示
    • 2、倒计时代码
    • 3、实现过程分析
  • 四、进度条
    • 1、效果展示
    • 2、进度条代码
      •    makefile
      •    头文件processBar.h
      •   .c 文件processBar.c
      •   .c文件main.c
    • 3、实现过程分析
      •   进度条实现样式
      •   进度条实现方法

一、理解回车换行

  在我们熟悉的C语言中,换行就可以跳转的下一行开头 ,但其实这一操作有两个步骤,\r (回车)和 \n(换行)

\r 回车就是回到这一行开头
\n 换行就是另起一行

二、认识行缓冲

  在内存中预留了一块空间,用来缓冲输入或输出的数据,这个保留的空间被称为缓冲区。下面我们通过几个代码例子来理解行缓冲概念

1、代码一、二(回车换行理解)

代码一:

  1#include <stdio.h>
  2 int main()
  3 {
  4     printf("hello world\n");                                                                                                                               
  5     return 0;
  6 }
代码二:
  1#include <stdio.h>
  2 int main()
  3 {
  4     printf("hello world\r");                                                                                                                               
  5     return 0;
  6 }

  不难发现 \n 可以打印出来,而 \r,不能打印出来,因为显示器模式是行刷新缓冲区是按行缓冲的,没有\n,就不能立即刷新。 \r 回到行首后,会进行覆盖写,shell 提示符会覆盖掉之前写的 “hello world”,如果我们在 “hello world” 不加 \r,则不会进行覆盖写,shell 提示符会顺着 “hello world” 往后写

如下:

2、代码三、四(sleep函数和ffush函数理解)

  行缓冲是缓冲区刷新策略的一种,在行缓冲模式下,当输入和输出中遇到 ‘\n’ 换行时,就会刷新缓冲区,下面我们认识头文件<unistd.h>的三个函数

s l e e p sleep sleep : Linux 下的休眠函数,单位是秒
u s l e e p usleep usleep:和sleep 一样,单位ms(即10-6 m)
f f l u s h fflush fflush :刷新缓冲区

代码 3:

  1 #include <stdio.h>
  2 #include <unistd.h>                                                                                                                                       
  3 int main()
  4 {
  5     printf("hello world");
  6     sleep(3);
  7     return 0;
  8 }

  我们知道函数代码语句是从上到下依次进行的,而我们看到的却是先休眠三秒,然后再打印出"hello world",原因是因为数据保存在缓冲区中,没有主动刷新。当程序退出后,保存在缓冲区中的数据被自动刷新出来了,如果我们想提前刷新,便可以调用 f f l u s h fflush fflush函数来刷新缓冲区

代码四:

  1 #include <stdio.h>
  2 #include <unistd.h>                                                                                                                                       
  3 int main()
  4 {
  5     printf("hello world");
  6		fflush(stdout);
  7		printf("\n");
  8     sleep(3);
  9     return 0;
  10}

  这次 “hello world” 被直接打印出来,我们加 \n避免 s h e l l shell shell 提示符出现在 “hello world” 后面

三、简单倒计时

1、效果展示

  有了以上的准备工作,能够让我们理解倒计时和进度条工作原理,下面我们先给代码和效果,在讲其中细节

2、倒计时代码

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 int main()
  4 {
  5     int cnt=10;
  6     while(cnt>=0)
  7     {
  8         printf("%-2d\r",cnt);
  9         fflush(stdout);
 10         sleep(1);
 11         cnt--;                                                                                                                                            
 12     }
 13     printf("\n");
 14     return 0;
 15 }

3、实现过程分析

1、定义倒计时变量 cnt,让其逐渐递降
2、核心就是用 \r 回到缓冲区行首进行覆盖写,然后fflush不断刷新出出来
3、格式调整,打印 cnt==10 时,在缓冲区打印的其实是字符1和字符0,如果我们不用 2d% 来调整格式,而用 d% 的话,那么覆盖写只会覆盖第一位字符 1 1 1 的位置,而第二位的字符 0 0 0, 还留在缓冲区原来的位置,于是倒计时便会变为下面这样
  10->90->80->70->60->50->40->30->20->10->00-2d% 加个负号保证其向左对齐
4、倒计时完加个 \n符,shell 提示符就不会出现在倒计时后面

四、进度条

1、效果展示


2、进度条代码

   makefile

  1 processbar:processBar.c main.c                                                                                                                            
  2     gcc -o $@ $^
  3 .PHONY:clean
  4 clean:
  5     rm -f processbar

   头文件processBar.h

  1 #pragma once                                                                                                                                              
  2 #include<stdio.h>
  3 
  4 #define SIZE 102
  5 #define BODY '='
  6 #define TAIL '>'
  7 
  8 extern void processbar(int rate);
  9 extern void initbar();

  .c 文件processBar.c

    1 #include "processBar.h"
    2 #include <string.h>
    3 #include <unistd.h>
    4 
    5 #define LIGHT_GREEN  "\033[1;32m" //亮绿色
    6 #define NONE "\033[m" 			//截断
    7 
    8 const char *lable="|/-\\";
    9 char bar[SIZE];
   10 
   11 void processbar(int rate)
   12 {
   13     if(rate<0 || rate > 100)
   14         return;
   15	  //没有\n,就没有立即刷新,因为显示器模式是行刷新
   16     printf(LIGHT_GREEN"[%-100s]"NONE"[%d%%][%c]\r",bar,rate,lable[rate%4]); 
   17     fflush(stdout);
   18     bar[rate++]=BODY;
   19     if(rate<100)
   20          bar[rate]=TAIL;
   21 }                                                                                                                                                       
   22                         
   23 void initbar()
   24 {             
   25     memset(bar,'\0',sizeof(bar));
   26 } 

  .c文件main.c

  1 #include "processBar.h"
  2 #include <unistd.h>
  3 
  4 typedef void(*callback_t)(int);
  5 void downLoad(callback_t cb)
  6 {
  7     initbar();
  8     int total=1000; // 1000MB
  9     int curr=0;     //0MB
 10     while(curr<=total)
 11     {
 12         // 进行某种下载任务
 13         usleep(50000);  //模拟下载花费时间
 14         int rate=curr*100/total;//更新进度
 15 
 16         cb(rate);       //回调展示进度
 17         //processbar(curr*100/total); 
 18 
 19         curr+=10;       // 循环下载了一部分,更新进度
 20     }
 21     printf("\n");
 22 }
 23 
 24 
 25 int main()
 26 {
 27     printf("download 1:\n");
 28     downLoad(processbar);
 29     printf("download 2:\n");                                                                                                                              
 30     downLoad(processbar);  
 31     printf("download 3:\n");  
 32     downLoad(processbar);  
 33     printf("download 4:\n");  
 34     downLoad(processbar); 
 35		return 0;
 36 }

3、实现过程分析

  进度条实现样式

进度条样式 :
   主体样式为两个中括号包裹,中间 => 推进的方式呈现,比如:[======>]
  主体右侧中括号位置保持不变,中间元素不断推进,比如:[=>     ]
  因此我们把中间主体 = 宏定义为 BODY ,把尾侧 > 宏定义为 TAIL

进度条百分比:
  显示当前加载进度,用 [rate%] 显示,rate 随着进度条的不断推进而变化,而打印 %(转义字符)则需要两个 %%

进度条旋转字符:
  显示加载样式,可以利用一个旋转的字符,例如 [] 的样式,顺时针不断旋转,依次为 “| / - \”,注意 \ 也是转义字符,因此需要两个 \ \,对此我们定义一个lable指针指向常量字符串const char *lable=" | / - \ "

进度条颜色: c语言颜色参考
  我们可以根据自己的喜好给进度条上色,在此我们找到颜色参照表
  把亮绿色宏定义为 #define LIGHT_GREEN “\033[1;32m”
  结束的地方宏定义为 #define NONE “\033[m”

  进度条实现方法

  预留进度条大小为 100 个 = ,外加 1 个 > ,加上保存 \0 的位置,建一个存储为102 (宏定义为SIZE)个单位的bar数组。processbar()函数,将某比率的进度条打印出来,\r 回到行首后,fflush 刷新缓冲区,同时bar数组尾插上 =,再插入 >,注意当rate为100时,进度条加载完毕,因此不需要再插入 >
  将其模拟为执行某个下载任务,把实现方法 processbar()函数 作为参数传递给 downLoad()模拟下载函数 ,对此我们定义一个processbar()类型的函数指针,重命名为 callback_t。我们定义下载包大小为 t o t a l total total ,当前进度为 c u r r curr curr ,因此进度比例为 rate=curr*100/total。用usleep函数模拟下载时间,然后循环起来回调processbar()函数,便实现了进度条,最后考虑到第二次下载,bar数组满了,我们再每次调用downLoad()函数时,清空bar数组

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/741740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mac上快速将视频转化为GIF动图

1、找到需要转为GIF的视频&#xff0c;使用QuickTime Player打开&#xff0c;找到屏幕左上角的QuickTime Player菜单&#xff0c;点击【编辑】-【修剪】 2、视频下方会出现一个时间轴&#xff0c;拖动选取自己想要的时间段&#xff0c;修剪完成后保存 3、右键剪辑好的视频&…

前端学习——Web API (Day4)

日期对象 实例化 日期对象方法 案例 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content…

【前端】网页开发精讲与实战 CSS Day 2

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;前端 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对你有…

『点云处理任务 』用PCL库 还是 深度学习模型?

深度学习和PCL库都可以用来做点云处理任务&#xff0c;但是二者侧重点有所不同。 1、PCL库&#xff08;点云库&#xff09;是一个专门用于点云处理和三维几何分析的开源类库&#xff0c;常用于以下任务&#xff1a; 1、点云滤波&#xff1a;用于去除噪音、下采样和平滑等操作&…

GM/T0015-2012学习笔记

GM/T0015-2012学习笔记 文章目录 GM/T0015-2012学习笔记数字证书数字证书特性用户证书形式 数字证书格式DER资料1资料2 //TODO 吐槽一下&#xff1a;既然是标准&#xff0c;就应该是广而告知&#xff0c;被一些信息查的网站&#xff0c;高价出售。 我从“密码行业标准化技术委…

一文读懂单分子标签UMI

背景 在整理分子标签&#xff08;unique molecular identifier&#xff0c;UMI&#xff09;之前&#xff0c;先了解下&#xff1a; NGS 中潜在的错误来源有哪些&#xff1f; 1. 来源建库过程&#xff1a;文库制备、靶向序列捕获和测序均涉及 DNA 聚合酶以及扩增步骤。这些过程…

和LangChain CEO一起讲解深度学习在数据领域的应用;如何识别语音DeepFake?

&#x1f989; AI新闻 &#x1f680; 如何识别语音DeepFake&#xff1f; 摘要&#xff1a;加拿大滑铁卢大学的研究人员开发了一种语音DeepFake软件&#xff0c;成功qipian语音认证系统概率高达99%。其他安全研究人员也开始应对这一技术挑战&#xff0c;亚马逊研究人员尝试检查…

【实验四】多态

1、完成第133页实验题目2 import java.util.Scanner;public class Application{private UserDao dao;public Application(UserDao dao){this.daodao;}public void setDao(UserDao dao){this.dao dao;}public void registe()//注册函数{Scanner scnnew Scanner(System.in);//获…

10分钟理解RNN、LSTM、Transformer结构原理!

文章目录 一、RNN1.1 RNN基本架构1.2 RNN经典的三种结构1.2.1 vector-to-sequence结构1.2.2 sequence-to-vector结构1.2.3 Encoder-Decoder结构 1.3 RNN常用领域1.4 RNN的优缺点1.5 RNN中为什么会出现梯度消失 二、LSTM2.1 LSTM与RNN差异2.2 LSTM核心思想图解2.2.1 忘记层门2.2…

小程序上传头像功能

前台wxml代码 点击navigator&#xff0c;跳转到裁剪页面 <navigator url"/pages/cropper/cropper?userid{{user._id}}&&imgSrc{{user.img}}" hover-class"none"><view class"user-logo-section"><text class"user…

1亿条数据批量插入 MySQL,哪种方式最快?

利用JAVA向Mysql插入一亿数量级数据—效率测评 这几天研究mysql优化中查询效率时&#xff0c;发现测试的数据太少&#xff08;10万级别&#xff09;&#xff0c;利用 EXPLAIN 比较不同的 SQL 语句&#xff0c;不能够得到比较有效的测评数据&#xff0c;大多模棱两可&#xff0c…

深化校企合作,开源网安为软件安全人才培养按下“加速键”

开源网安一直以来十分重视网络安全人才的培养&#xff0c;已陆续与湖北大学、武汉工业大学、桂林电子科技大学等多所高校建立战略合作&#xff0c;打造产学研协同的多类型人才培养模式。6月29日&#xff0c;开源网安与桂林电子科技大学携手举办了软件安全开发与DevSecOps实训课…

简要介绍 | 心脏机械-电耦合理论:原理、研究现状与未来展望

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对心脏机械-电耦合理论进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 心脏机械-电耦合理论&#xff1a;原理、研究现状与未来展望 心脏中精密的血流局部调控机制&#xff1a;electro-metabolic…

使用ChatGPT进行个性化学习

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 3D工具集&#xff1a; NSDT简石数字孪生 在这篇文章中&#xff0c;您将发现 ChatGPT 作为机器学习和数据科学爱好者的个人导师的好处。特别是&#xff0c;您将学习 如何让ChatGPT引导你学习抽象代数如何让 ChatGPT 帮助您…

代码随想录day9

28. 找出字符串中第一个匹配项的下标 思路&#xff1a; 没有。。。。真不会。。。。下次再来吧 代码&#xff1a; def strStr(self, haystack: str, needle: str) -> int:if not needle:return 0next [0] * len(needle)self.getNext(next, needle)j -1for i in range(…

路径规划算法:基于猎食者优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于猎食者优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于猎食者优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

如何搭建自己的图床(GitHub版)

文章目录 1.图床的概念2.用GitHub创建图床服务器2.1.新建仓库2.2.生成Token令牌2.3.创建img分支和该分支下的img文件夹(可选) 3.使用PicGo软件上传图片3.1 下载PicGo软件3.2配置PicGo3.3用PicGo实现上传 4. Typora实现自动上传5.免费图片网站 前言&#xff1a; 如果没有自己的服…

暑假第六天打卡

离散&#xff1a; 极小项&#xff1a; &#xff08;1&#xff09;简单合取式 &#xff08;2&#xff09;每个字母只出现一次 &#xff08;3&#xff09;按字典顺序排列 &#xff08;4&#xff09;成真赋值&#xff0c;且化为十进制 极大项 &#xff08;1&#xff09;简单…

智能化客流系统-实时监测人流趋势,助力商场销售策略优化

随着人们对安全和便利性的要求不断提高&#xff0c;智慧客流人数管理系统的应用已经成为各类场所管理的必备工具。它可以帮助管理者实时监测人流情况&#xff0c;提供精准的服务和安全保障。 一、案例展示 智慧客流人数管理系统在图书馆的应用&#xff0c;通过实时监测和数据…

avue 表单绑定值;avue表单项根据某项的值去联动显隐或是联动下拉数据

效果&#xff1a;发布type为shp时 数据相关的都隐藏&#xff0c;当发布type为postgis时则显示 1.avue表单绑定值 html <avue-form :option"option" v-model"publishForm"></avue-form> js data中定义 data() {return {publishForm: {},optio…