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

《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第一个小程序-进度条的实现

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…...

【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 启动报错异常&#xff0c;导致docker无法启动成功 我们看到问题出在hyper-v的问题上&#xff0c;搜索解决方法&#xff0c;官网常见问题如下 Overview | Docker Documentation 二、解决 Hyper-V 已安装并正常工作 在BIOS中启用虚拟化 Wind…...

socket server服务器开发常见的并发模型

两种高效的事件处理模式 服务器程序通常需要处理三类事件&#xff1a;I/O 事件、信号及定时事件。有两种高效的事件处理模式&#xff1a;Reactor和 Proactor&#xff0c;同步 I/O 模型通常用于实现Reactor 模式&#xff0c;异步 I/O 模型通常用于实现 Proactor 模式。 无论是 …...

怎么修改pdf文件中的文字?分享几种编辑方法

怎么修改pdf文件中的文字&#xff1f;PDF格式的文件通常具有很高的可读性和稳定性&#xff0c;但是如果需要修改其中的文字&#xff0c;就需要使用专门的PDF编辑器。本文将介绍几种PDF编辑的方法&#xff0c;下面就跟着我一起来看看这几款工具吧。 方法一&#xff1a;使用迅捷P…...

spring — Spring Security 5.7与6.0差异性对比

1. spring security Spring Security 是一个提供身份验证、授权和针对常见攻击保护的框架。 凭借对保护命令式和反应式应用程序的一流支持&#xff0c;它成为基于Spring的标准安全框架。 Spring Security 在最近几个版本中配置的写法都有一些变化&#xff0c;很多常见的方法都…...

道本科技受邀参加建筑产业互联网推动建筑产业现代化体系构建座谈会,以数字化产品为建筑行业注入新动能!

2023年7月底&#xff0c;道本科技作为中国建筑业协会合作伙伴&#xff0c;受邀参加了建筑产业互联网推动建筑产业现代化体系构建座谈会。在这次座谈会上&#xff0c;道本科技旗下产品“合规数”“合同智能审查”和“智合同范本库”被中国建筑&#xff08;中小企业&#xff09;产…...

数据结构----效率问题

数据结构----效率问题 一.衡量效率 1.衡量效率的两个维度 1.时间维度&#xff1a;时间复杂度&#xff1a;Time Complexity 时间复杂度是代码总的运行次数&#xff08;粗糙&#xff09; 2.空间维度&#xff1a;空间复杂度&#xff1a;Space Complexity 空间复杂度是额外申…...

【BASH】回顾与知识点梳理(五)

【BASH】回顾与知识点梳理 五 五. 数据流重导向5.1 什么是数据流重导向standard output 与 standard error output/dev/null 垃圾桶黑洞装置与特殊写法standard input &#xff1a; < 与 << 5.2 命令执行的判断依据&#xff1a; ; , &&, ||cmd ; cmd (不考虑指…...

PCL点云处理之最小二乘空间直线拟合(3D) (二百零二)

PCL点云处理之最小二乘空间直线拟合(3D) (二百零二) 一、算法简介二、实现代码三、效果展示一、算法简介 对于空间中的这样一组点:大致呈直线分布,散乱分布在直线左右, 我们可采用最小二乘方法拟合直线,更进一步地,可以通过点到直线的投影,最终得到一组严格呈直线分布…...

大数据课程G1——Hbase的概述

文章作者邮箱&#xff1a;yugongshiyesina.cn 地址&#xff1a;广东惠州 ▲ 本章节目的 ⚪ 了解HIve的概念&#xff1b; ⚪ 了解HIve与数据库的区别&#xff1b; ⚪ 了解HIve的特点&#xff1b; 一、简介 1. 概述 1. HBase原本是由Yahoo!公司开发后来贡献给了…...

第三章 图论 No.2单源最短路之虚拟源点,状压最短路与最短路次短路条数

文章目录 1137. 选择最佳线路1131. 拯救大兵瑞恩1134. 最短路计数383. 观光 dp是特殊的最短路&#xff0c;是无环图&#xff08;拓扑图&#xff09;上的最短路问题 1137. 选择最佳线路 1137. 选择最佳线路 - AcWing题库 // 反向建图就行 #include <iostream> #include…...

汉诺塔问题

一本通1205&#xff1a;汉诺塔问题 【题目描述】 约19世纪末&#xff0c;在欧州的商店中出售一种智力玩具&#xff0c;在一块铜板上有三根杆&#xff0c;最左边的杆上自上而下、由小到大顺序串着由64个圆盘构成的塔。目的是将最左边杆上的盘全部移到中间的杆上&#xff0c;条件…...

Java on Azure Tooling 6月更新|标准消费和专用计划及本地存储账户(Azurite)支持

作者&#xff1a;Jialuo Gan - Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎阅读 Java on Azure 工具的六月更新。在本次更新中&#xff0c;我们将介绍 Azure Spring Apps 标准消费和专用计划支持以及本地存储账户&…...

Prometheus(八)-网络嗅探-黑盒监控

介绍 Blackbox Exporter是Prometheus社区提供的官方黑盒监控解决方案&#xff0c;其允许用户通过&#xff1a;HTTP、HTTPS、DNS、TCP以及ICMP的方式对网络进行探测。用户可以直接使用go get命令获取Blackbox Exporter源码并生成本地可执行文件&#xff1a; go get prometheus…...

modbus TCP 通信测试

modbus TCP 通信测试 读取单个或多个线圈 发送指令&#xff1a;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&#xff1a;后面的字节长度。 01&am…...

GDB Debug

使用gdb带着参数启动程序 在gdb中启动程序并传递命令行参数&#xff1a; gdb ./my_program (gdb) run arg1 arg2 arg3 这将在gdb中启动程序"my_program"&#xff0c;并将参数"arg1"、"arg2"和"arg3"传递给程序。 在启动gdb之前&…...

【项目流程】前端项目的开发流程

1. 项目中涉及的所有角色及其职责 - PM 产品经理 产品经理&#xff08;Product Manager&#xff0c;简称PM&#xff09;负责明确和定义产品的愿景和战略&#xff0c;与客户、用户、业务部门和其他利益相关者进行沟通&#xff0c;收集并分析他们的需求和期望。负责制定产品的详…...

JS监听浏览器关闭、刷新及切换标签页触发事件

蛮简单的东西&#xff0c;知道就会&#xff0c;不知道就不会&#xff0c;没什么逻辑可言。简单记录一下&#xff0c;只为加深点儿印象。 visibilitychange visibilitychange可以监听到浏览器的切换标签页。 直接上代码&#xff1a; <script>document.addEventListe…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

遍历 Map 类型集合的方法汇总

1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序

一、开发环境准备 ​​工具安装​​&#xff1a; 下载安装DevEco Studio 4.0&#xff08;支持HarmonyOS 5&#xff09;配置HarmonyOS SDK 5.0确保Node.js版本≥14 ​​项目初始化​​&#xff1a; ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...

全志A40i android7.1 调试信息打印串口由uart0改为uart3

一&#xff0c;概述 1. 目的 将调试信息打印串口由uart0改为uart3。 2. 版本信息 Uboot版本&#xff1a;2014.07&#xff1b; Kernel版本&#xff1a;Linux-3.10&#xff1b; 二&#xff0c;Uboot 1. sys_config.fex改动 使能uart3(TX:PH00 RX:PH01)&#xff0c;并让boo…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案&#xff1a;Java 字节码技术实战分享&#xff08;仅供学习&#xff09; 一、Aspose.PDF 简介二、说明&#xff08;⚠️仅供学习与研究使用&#xff09;三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...