《Linux从练气到飞升》No.07 Linux第一个小程序-进度条的实现
🕺作者: 主页
我的专栏 C语言从0到1 探秘C++ 数据结构从0到1 探秘Linux 菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言
🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的很重要,有问题可在评论区提出,感谢阅读!!!
前言
前面几章我们讲述了Linux指令、权限管理、编辑器、编译器、软件包管理器、自动化管理工具,也写了简单的”Hello World“程序,但是没有实现过复杂一点的程序,光说不练假把式,今天就带大家来做一个小项目–进度条。
搭建框架
在写代码之前,我们先把文件先建好。
vim main.c
vim process.c
vim process.h
vim makefile
书写代码
在写代码要先讲一个知识点。
1.回车换行
在我们日常使用回车键时,是否注意到,当我们按下回车键,也就是\n,光标就会换到第二行的开始,其实这里面有两个动作,换行和把光标设置到行开始,在C语言中可用\r来把光标换到开始位置
我们来借此写个小demo:倒计时void download() {int cnt=10;while(cnt!=0){printf("%-2d\r",cnt);fflush(stdout);cnt--;sleep(1);}printf("\n"); }
效果如下:

第一版
我们最终要实现这个效果:

我们前面讲了\r可以把光标移到行始,所以在我们输出缓存字符的时候,每一次都移到一开始的位置,随着缓存字符的增多,来实现进度条的效果。
代码如下:
process.c
#include"process.h"
const char *lable="|/-\\";//通过循环实现一个转动的效果
char bar[NUM]; void download(int speed)
{ char bar[NUM];//使用数组来存储”缓存字符“ memset(bar,'\0',sizeof(bar));//初始化 int len =strlen(lable); int cnt=0; while(cnt<=TOP)//设置终止条件 { printf("[%-100s][%d%%][%c]\r", bar, cnt, lable[cnt%len]);//%-100s:预留100个空间左对齐//%%:输出%,也可以使用\%//\r:把光标移到开始位置 fflush(stdout);//清空缓存区 bar[cnt++]=BODY;//将cnt所在位置设置为”BODY" if(cnt<100)bar[cnt]=RIGHT;//设置> usleep(speed);//控制进度条的速度,单位是微秒 } printf("\n");
}
main.c
#include "process.h"int main()
{download(100000);return 0;
}
process.h
#pragma once
#include<stdio.h>
#include <unistd.h>
#include<string.h>#define NUM 102
#define TOP 100
#define BODY '='
#define RIGHT '>'extern void download(int speed);
makefile
process:process.c main.c gcc -o $@ $^ .PHONY:clean clean: rm -f process
通过注释,应该可以清楚明白代码的实现原理,但是进度条该怎么用呢?这是一个问题,下面我们来模拟一下使用场景,只需要再修改一下代码即可。
第二版
参考代码注释理解
main.c
#include "processBar.h"typedef void (*callback_t)(int); // 函数指针类型// 模拟一种安装或者下载
void downLoad(callback_t cb)
{int total = 1000; // 1000MBint curr = 0; // 0MBwhile(curr <= total){// 模拟进行着某种下载的任务, 我usleep(50000); // 模拟下载花费的时间int rate = curr*100/total; // 更新进度cb(rate); // 通过回调,展示进度curr += 10; // 循环下载了一部分}printf("\n");
}int main()
{printf("donwnload 1: \n");downLoad(processbar);initbar();printf("donwnload 2: \n");downLoad(processbar);initbar();printf("donwnload 3: \n");downLoad(processbar);initbar();printf("donwnload 4: \n");downLoad(processbar);initbar();return 0;
}
processBar.h
#pragma once#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>#define NUM 102
#define TOP 100
#define BODY '='
#define RIGHT '>'extern void processbar(int rate);
extern void initbar();
processBar.c
#include "processBar.h"const char *lable="|/-\\";
char bar[NUM];// 是如何被调用的
void processbar(int rate)
{if(rate < 0 || rate > 100) return;int len = strlen(lable);printf("[%-100s]""[%d%%][%c]\r", bar, rate, lable[rate%len]); // 没有\n,就没有立即刷新,因为显示器模式是行刷新fflush(stdout);bar[rate++] = BODY;if(rate < 100) bar[rate] = RIGHT;
}void initbar()
{memset(bar, '\0', sizeof(bar));
}
makefile
processbar:processBar.c main.cgcc -o $@ $^
.PHONY:clean
clean:rm -f processbar
效果是一样的,看到这里,我相信你对实现一个进度条已经非常了解了,但是有没有觉得它有点不好看,那么我们再来优化一下。
第三版
怎么修改?这里要了解一下怎么让编译器输出颜色,可参考这篇文章
http://t.csdn.cn/O2T8F
只需修改processBar.c文件即可
如下:
#include "processBar.h"const char *lable="|/-\\";
char bar[NUM];// 是如何被调用的
void processbar(int rate)
{if(rate < 0 || rate > 100) return;int len = strlen(lable);printf("\033[38;2;128;0;128m\033[48;2;255;255;255m[%-100s][%d%%][%c]\033[m\r", bar, rate, lable[rate % len]);fflush(stdout);bar[rate++] = BODY;if(rate < 100) bar[rate] = RIGHT;
}void initbar()
{memset(bar, '\0', sizeof(bar));
}
效果如下:

后记
本篇我们讲述了如何在Linux上实现一个进度条,并对其进行了美化,但是我们的目的是通过做项目来把之前所学的相关知识串起来,我并没有对它进行过多的讲解,因为它本身并不难,难的是你在linux系统上编程的过程,但它也是最重要的!
相关文章:
《Linux从练气到飞升》No.07 Linux第一个小程序-进度条的实现
🕺作者: 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 😘欢迎关注:👍点赞🙌收藏✍️留言 🏇码字不易,你的👍点赞🙌收藏❤️关注对我真的…...
【NLP概念源和流】 04-过度到RNN(第 4/20 部分)
接上文 【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分) 一、说明 词嵌入使许多NLP任务有了显著的改进。它对单词原理图的理解以及将不同长度的文本表示为固定向量的能力使其在许多复杂的NLP任务中非常受欢迎。大多数机器学习算法可以直接应用于分类和回归任务的…...
企业上云实施路线图
企业上云步骤主要分为规划、设计、实施、验证、运维五个阶段。https://articles.e-works.net.cn/cloud/article144684.htm...
docker系列--解决hyper-v导致docker无法启动问题
一、问题 windows docker desktop 启动报错异常,导致docker无法启动成功 我们看到问题出在hyper-v的问题上,搜索解决方法,官网常见问题如下 Overview | Docker Documentation 二、解决 Hyper-V 已安装并正常工作 在BIOS中启用虚拟化 Wind…...
socket server服务器开发常见的并发模型
两种高效的事件处理模式 服务器程序通常需要处理三类事件:I/O 事件、信号及定时事件。有两种高效的事件处理模式:Reactor和 Proactor,同步 I/O 模型通常用于实现Reactor 模式,异步 I/O 模型通常用于实现 Proactor 模式。 无论是 …...
怎么修改pdf文件中的文字?分享几种编辑方法
怎么修改pdf文件中的文字?PDF格式的文件通常具有很高的可读性和稳定性,但是如果需要修改其中的文字,就需要使用专门的PDF编辑器。本文将介绍几种PDF编辑的方法,下面就跟着我一起来看看这几款工具吧。 方法一:使用迅捷P…...
spring — Spring Security 5.7与6.0差异性对比
1. spring security Spring Security 是一个提供身份验证、授权和针对常见攻击保护的框架。 凭借对保护命令式和反应式应用程序的一流支持,它成为基于Spring的标准安全框架。 Spring Security 在最近几个版本中配置的写法都有一些变化,很多常见的方法都…...
道本科技受邀参加建筑产业互联网推动建筑产业现代化体系构建座谈会,以数字化产品为建筑行业注入新动能!
2023年7月底,道本科技作为中国建筑业协会合作伙伴,受邀参加了建筑产业互联网推动建筑产业现代化体系构建座谈会。在这次座谈会上,道本科技旗下产品“合规数”“合同智能审查”和“智合同范本库”被中国建筑(中小企业)产…...
数据结构----效率问题
数据结构----效率问题 一.衡量效率 1.衡量效率的两个维度 1.时间维度:时间复杂度:Time Complexity 时间复杂度是代码总的运行次数(粗糙) 2.空间维度:空间复杂度:Space Complexity 空间复杂度是额外申…...
【BASH】回顾与知识点梳理(五)
【BASH】回顾与知识点梳理 五 五. 数据流重导向5.1 什么是数据流重导向standard output 与 standard error output/dev/null 垃圾桶黑洞装置与特殊写法standard input : < 与 << 5.2 命令执行的判断依据: ; , &&, ||cmd ; cmd (不考虑指…...
PCL点云处理之最小二乘空间直线拟合(3D) (二百零二)
PCL点云处理之最小二乘空间直线拟合(3D) (二百零二) 一、算法简介二、实现代码三、效果展示一、算法简介 对于空间中的这样一组点:大致呈直线分布,散乱分布在直线左右, 我们可采用最小二乘方法拟合直线,更进一步地,可以通过点到直线的投影,最终得到一组严格呈直线分布…...
大数据课程G1——Hbase的概述
文章作者邮箱:yugongshiyesina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解HIve的概念; ⚪ 了解HIve与数据库的区别; ⚪ 了解HIve的特点; 一、简介 1. 概述 1. HBase原本是由Yahoo!公司开发后来贡献给了…...
第三章 图论 No.2单源最短路之虚拟源点,状压最短路与最短路次短路条数
文章目录 1137. 选择最佳线路1131. 拯救大兵瑞恩1134. 最短路计数383. 观光 dp是特殊的最短路,是无环图(拓扑图)上的最短路问题 1137. 选择最佳线路 1137. 选择最佳线路 - AcWing题库 // 反向建图就行 #include <iostream> #include…...
汉诺塔问题
一本通1205:汉诺塔问题 【题目描述】 约19世纪末,在欧州的商店中出售一种智力玩具,在一块铜板上有三根杆,最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到中间的杆上,条件…...
Java on Azure Tooling 6月更新|标准消费和专用计划及本地存储账户(Azurite)支持
作者:Jialuo Gan - Program Manager, Developer Division at Microsoft 排版:Alan Wang 大家好,欢迎阅读 Java on Azure 工具的六月更新。在本次更新中,我们将介绍 Azure Spring Apps 标准消费和专用计划支持以及本地存储账户&…...
Prometheus(八)-网络嗅探-黑盒监控
介绍 Blackbox Exporter是Prometheus社区提供的官方黑盒监控解决方案,其允许用户通过:HTTP、HTTPS、DNS、TCP以及ICMP的方式对网络进行探测。用户可以直接使用go get命令获取Blackbox Exporter源码并生成本地可执行文件: go get prometheus…...
modbus TCP 通信测试
modbus TCP 通信测试 读取单个或多个线圈 发送指令:00 00 00 00 00 06 00 01 03 10 00 08 00 00 00 00 00 06 00 01 03 10 00 08 事务 处理 标识 协议 标识 长度 单元 标识 功能码 起始 线圈 地址 线圈 个数 06:后面的字节长度。 01&am…...
GDB Debug
使用gdb带着参数启动程序 在gdb中启动程序并传递命令行参数: gdb ./my_program (gdb) run arg1 arg2 arg3 这将在gdb中启动程序"my_program",并将参数"arg1"、"arg2"和"arg3"传递给程序。 在启动gdb之前&…...
【项目流程】前端项目的开发流程
1. 项目中涉及的所有角色及其职责 - PM 产品经理 产品经理(Product Manager,简称PM)负责明确和定义产品的愿景和战略,与客户、用户、业务部门和其他利益相关者进行沟通,收集并分析他们的需求和期望。负责制定产品的详…...
JS监听浏览器关闭、刷新及切换标签页触发事件
蛮简单的东西,知道就会,不知道就不会,没什么逻辑可言。简单记录一下,只为加深点儿印象。 visibilitychange visibilitychange可以监听到浏览器的切换标签页。 直接上代码: <script>document.addEventListe…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
