【Linux】从0到1实现一个进度条小程序

 
个人主页:🍝在肯德基吃麻辣烫
我的gitee:gitee仓库
分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处
文章目录
- 前言
 - 一、理解回车 '\r' 和换行 '\n'
 - 二、初步认识缓冲区
 - 1. 认识第一个函数:sleep
 - 2.观察缓冲区出现的现象
 - 3. 认识第二个函数:fflush
 
- 三、开始输出进度条
 - 了解倒计时
 - 准备工作
 
- 总结
 
进度条实现:

前言
本文讲解如何从0到1实现一个进度条小程序。
一、理解回车 ‘\r’ 和换行 ‘\n’
我们在写作文的时候,写到了一行的结尾,就得另起一行并到开头继续写。
其中,这个另起一行的动作就是"换行"
 回到开头的动作就是"回车"
"回车"这个动作对应的c语言的转义字符是 ‘\r’"换行"这个动作对应的c语言的转义字符是 ‘\n’
但是,\n其实包含了回车和换行两个动作。
 我们的键盘上面的回车键也是同时包含回车和换行两个动作。
二、初步认识缓冲区
1. 认识第一个函数:sleep
sleep(1);
 
sleep函数的功能是让计算机等待指定秒数(单位:秒)后再继续启动。
 知道sleep的功能即可。
还有一个睡眠函数:usleep,它们的功能相同,只不过这个函数的单位是微秒。
1秒 = 1000毫秒
1毫秒= 1000微秒
2.观察缓冲区出现的现象
来看第一段代码出现的现象:
  2 #include "process.h"3 4 int main()5 {6     printf("Hello Linux\n");7     sleep(2);8 9     return 0;10 }        
 
现象:

 第二段代码:
  2 #include "process.h"3 4 int main()5 {6     printf("Hello Linux");7     sleep(2);                                                                                                                        8 9     return 0;10 }
 
现象:

通过这两段代码以及出现的现象可知:
- 1.第一段代码是直接弹出 “Hello Linux” 字段后两秒,再弹出指令行。
 - 2.第二段代码是两秒过后,再打印"Hello Linux",并且指令行是紧随其后的。
 
问:第一个现象是先执行printf函数还是先执行sleep函数?
实际上,c语言是从上往下扫描代码的,所以一定是先执行printf函数。那么,在sleep两秒期间,printf函数去哪了呢?
一定是被保存起来了。
这个保存的东西,就叫做缓冲区
在c语言有一块内存叫做缓冲区。
缓冲区是由c语言维护的一块内存空间。
到这里就可以解答第一个现象了,首先执行printf函数,输出Hello Linux,先保存到缓冲区中,2秒后再输出到显示器文件中,由于没有换行,后面则紧跟着指令条。
为什么第二个现象是马上就输出Hello Linux,再睡眠两秒呢?
这是因为'\n'这个换行符,具有刷新缓冲区的功能。
也就是把缓冲区里面的东西给刷掉,让它走它该走的地方,别停留在缓冲区里面了。
至此我们可以解释第二个现象了:Hello Linux字符串其实是先保存到缓冲区中的,然而
遇到'\n'这个换行符刷新后,将该字符串输出到了显示器文件中,再执行2秒休眠,这
才是我们看到的东西。
3. 认识第二个函数:fflush
在c程序中会默认打开三个流:标准输入流,标准输出流,标准错误流。
 这里只考虑标准输出流,该流的默认数据是stdout,也就是显示器文件。
fflush函数的功能是:将缓冲区的内容写入到标准输出流。
 通俗一点就是将缓冲区的内容打印到屏幕上。
有了这个函数,接下来我们就可以实现进度条小程序了。
三、开始输出进度条
了解倒计时
要实现进度条,首先要知道它每一步要输出什么。
 首先讲一讲倒计时,我们见过的倒计时是这样的:
 
 这里有一个需要注意的地方:
- 每一个数字都会覆盖上一个数字
 
就用到开头讲到的'\r'回车符,每次输出数字后,将光标回到当前行开头,再输出,就能将上一个数字覆盖。
具体代码如下:
  2 #include "process.h"3 4 int main()5 {6     int cnt = 9;7     while(cnt)8     {9        printf("%d\r",cnt--);10        fflush(stdout);                                                                                                               11        sleep(1);12     }13     return 0;14 }
~ 
效果如下:

准备工作
知道倒计时怎么走后,我们的进度条的过程是类似的:
 
 输出的过程如上,只是每一次都把数据+1,并输出在当前行,达到一个慢慢增加的效果。(这里为了演示过程,实际上每次输出数据都是输出在同一行)
- 准备一个
buf数组,数组大小为102 -  
- 将数组的所有元素初始化成
'\0',这样每次输入都会遇到'\0'而终止 
 - 将数组的所有元素初始化成
 - 可以给一个小圆圈光标,
const char* lable = "|/-\\",意思是:每增加%1,光标就会变化。(这里有两个"\"是为了将转义字符’‘变成一个单纯的’') - 效果如下:

 - 当我们输出进度条时(这个进度条的身体由你来决定),我们应该提前保留100个位置给进度条进行输出。也就是:
%s–>%-100s - 同理,如开头看到的效果展示,为了输出%(百分号),我们需要两个百分号来输出一个单纯的百分号。
 
到此,贴出代码,就可以实现进度条啦!
process.h文件
  1                                                                                          2 #include <stdio.h>                                                   3 #include <unistd.h>                                                  4 #include <string.h>                                                                  5                                                                                                                                      6 void process();   
 
process.c文件
  1  #include"process.h"                                                                                                                 2 #define SIZE 1023 #define BODY '='4 #define HEAD '>'5                 6 char bar[SIZE]; 7 const char* lable = "|\\-/";8                             9 void process()              10 {             11     int cnt = 0;12     memset(bar,'\0',sizeof(bar));13     char c = HEAD;               14     while(cnt<100)               15     {             16         int len = strlen(lable);17         bar[cnt++] = BODY;      18         if(cnt < 100)           19              bar[cnt] = c;20         printf("[%-100s][%d%%][%c]\r",bar,cnt,lable[cnt%len]);21         fflush(stdout);                                       22         usleep(100000);                                       23                        24     }                  25     printf("\n");26 }    
 
main.c文件
  1 2 #include "process.h"3 4 int main()5 {6     process();                                                                                                                       7     return 0;8 } 
一个进度条就新鲜出炉啦!
总结
今天的文章讲了如何在Linux上实现一个进度条小程序,做这个进度条小程序的核心是理解’\r’和’\n’两个转义字符,以及缓冲区的概念,理解之后,实现起来就不难啦。
相关文章:
【Linux】从0到1实现一个进度条小程序
个人主页:🍝在肯德基吃麻辣烫 我的gitee:gitee仓库 分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处 文章目录 前言一、理解回车 \r 和换行 \n二、初步认识缓冲区1. 认识第一个函数:sleep2.观察缓冲区…...
江南大学轴承数据故障诊断(利用一维CNN进行故障诊断,代码和数据放在压缩包,无需修改任何东西,解压缩后直接运行,有详细注释)
1.江南大学轴承数据集介绍 采样频率:50khz,采样时间:10s 转速:600 800 1000/rpm 内圈:ib 外圈:ob 滚动体:tb 正常:N 以600转速下的内圈故障数据为例展示: 开始数据…...
【网络基础实战之路】基于BGP协议连接三个AS区域的实战详解
系列文章传送门: 【网络基础实战之路】设计网络划分的实战详解 【网络基础实战之路】一文弄懂TCP的三次握手与四次断开 【网络基础实战之路】基于MGRE多点协议的实战详解 【网络基础实战之路】基于OSPF协议建立两个MGRE网络的实验详解 【网络基础实战之路】基于…...
基于Python爬虫+词云图+情感分析对某东上完美日记的用户评论分析
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
Day 26 C++ list容器(链表)
文章目录 list基本概念定义结构双向迭代器优点缺点List和vector区别存储结构内存管理迭代器稳定性随机访问效率 list构造函数——创建list容器函数原型示例 list 赋值和交换函数原型 list 大小操作函数原型示例 list 插入和删除函数原型示例 list 数据存取函数原型注意示例 lis…...
【深度学习注意力机制系列】—— SKNet注意力机制(附pytorch实现)
SKNet(Selective Kernel Network)是一种用于图像分类和目标检测任务的深度神经网络架构,其核心创新是引入了选择性的多尺度卷积核(Selective Kernel)以及一种新颖的注意力机制,从而在不增加网络复杂性的情况…...
Markdown语法和表情
Markdown语法和表情 1. 标题2. 段落3. 加粗和斜体4.分隔线5.删除线6.下划线7.引用8.列表9.链接10. 图片11. 代码12.Markdown 表格其他1.支持的 HTML 元素2.转义3.公式 Markdown表情参考 Markdown 是一种轻量级的标记语言,用于简洁地编写文本并转换为HTML。它的语法简…...
CSDN编纂目录索引跳转设置
CSDN编纂目录索引跳转设置 文章目录 题目第一小节第二小节第三小节结论 题目 第一小节 第二小节 第三小节 结论...
cpu的架构
明天继续搞一下cache,还有后面的, 下面是cpu框架图 开始解释cpu 1.控制器 控制器又称为控制单元(Control Unit,简称CU),下面是控制器的组成 1.指令寄存器IR:是用来存放当前正在执行的的一条指令。当一条指令需要被执行时,先按…...
FastAPI和Flask:构建RESTful API的比较分析
Python 是一种功能强大的编程语言,广泛应用于 Web 开发领域。FastAPI 和 Flask 是 Python Web 开发中最受欢迎的两个框架。本文将对 FastAPI 和 Flask 进行综合对比,探讨它们在语法和表达能力、生态系统和社区支持、性能和扩展性、开发工具和调试支持、安…...
用康虎云报表打印二维码
用康虎云报表打印二维码 1 安装: 下载地址: https://www.khcloud.net/cfprint_download, 选择Odoo免代码报表模块和自定义SQL报表模块 下载下来后解压缩,一共有四个模块 cf_report_designer # 报表设计模块 cf_sale_print_ext # 演示模块 cf_sql_report cfprint …...
网盘直链下载助手
一、插件介绍 1.介绍 这是一款免费开源获取网盘文件真实下载地址的油猴脚本,基于 PCSAPI,支持 Windows,Mac,Linux 等多平台,支持 IDM,XDown,Aria2 等多线程下载工具,支持 JSON-RPC…...
【EI复现】售电市场环境下电力用户选择售电公司行为研究(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
并发——何谓悲观锁与乐观锁
乐观锁对应于生活中乐观的人总是想着事情往好的方向发展,悲观锁对应于生活中悲观的人总是想着事情往坏的方向发展。这两种人各有优缺点,不能不以场景而定说一种人好于另外一种人。 悲观锁 总是假设最坏的情况,每次去拿数据的时候都认为别人会…...
【C++】模板
1.模板的概念 2.函数模板基本语法 3.未完待续。。。 https://www.bilibili.com/video/BV1et411b73Z?p169&spm_id_frompageDriver&vd_sourcefb8dcae0aee3f1aab700c21099045395...
【Echart地图】jQuery+html5基于echarts.js中国地图点击弹出下级城市地图(附完整源码下载)
文章目录 写在前面涉及知识点实现效果1、实现中国地图板块1.1创建dom元素1.2实现地图渲染1.3点击地图进入城市及返回 2、源码分享2.1 百度网盘2.2 123云盘2.3 邮箱留言 总结 写在前面 这篇文章其实我主要是之前留下的一个心结,依稀记得之前做了一个大屏项目的时候&…...
Python AI 绘画
Python AI 绘画 本文我们将为大家介绍如何基于一些开源的库来搭建一套自己的 AI 作图工具。 需要使用的开源库为 Stable Diffusion web UI,它是基于 Gradio 库的 Stable Diffusion 浏览器界面 Stable Diffusion web UI GitHub 地址:GitHub - AUTOMATI…...
mongodb:环境搭建
mongodb 是什么? MongoDB是一款为web应用程序和互联网基础设施设计的数据库管理系统。没错MongoDB就是数据库,是NoSQL类型的数据库 为什么要用mongodb? (1)MongoDB提出的是文档、集合的概念,使用BSON&am…...
Grafana技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》
阿丹: Prometheus技术文档--基本安装-docker安装并挂载数据卷-《十分钟搭建》_一单成的博客-CSDN博客 在正确安装了Prometheus之后开始使用并安装Grafana作为Prometheus的仪表盘。 一、拉取镜像 搜索可拉取版本 docker search Grafana拉取镜像 docker pull gra…...
【Github】Uptime Kuma:自托管监控工具的完美选择
简介: Uptime Kuma 是一款强大的自托管监控工具,通过简单的部署和配置,可以帮助你监控服务器、VPS 和其他网络服务的在线状态。相比于其他类似工具,Uptime Kuma 提供更多的灵活性和自由度。本文将介绍 Uptime Kuma 的功能、如何使…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
