【Linux系统编程】进度条的编写
目录
一,进度条的必备知识
1,缓冲区的粗略介绍
2,回车与换行
二,进度条的初步制作
1,进度条的初步矿建
2,进度条的版本一
3,进度条的版本二
一,进度条的必备知识
1,缓冲区的粗略介绍
缓冲区是内存的一部分空间,用于临时存储输入和输出的数据。它可分为输入缓冲区和输出缓冲区。每当我们输入数据时都是往输入缓冲区中存放数据,当刷新缓冲区时,数据将会从缓冲区中拿出输入到某个变量中。每当我们输出数据时,系统将会把数据输出到输出缓冲区中,当刷新输出缓冲区时,数据将会从输出缓冲区输出到指定地方。
其中,缓冲区的刷新时机是不同的。行缓冲会在遇到换行符时刷新,全缓冲会在缓冲区写满时刷新,而无缓冲则没有缓冲区,代表是系统调用。在C/C++中,通常用 fflush(FILE* stream) 来强制刷新指定流的缓冲区。
C/C++中类似于sleep函数功能控制的就是缓冲区,当系统调用到sleep是,将会被缓冲区暂时保存起来,一旦sleep运行完毕之后缓冲区才刷新。进度条有时控制的就是缓冲区的刷新时间。
2,回车与换行
“ 回车 ” 是把光标从当前位置直接指向最开头位置。“ 换行 ” 是把光标从当前位置直接指向下一行同一列的位置。我们在C语言阶段常用的 “ \n ” 指的是 换行 + 回车。而 “ \r ” 只表示回车。
二,进度条的初步制作
1,进度条的初步矿建
首先,我们先来编写进度条的简单倒计时程序,这就需要运用回车和sleep来控制程序的运行。
#include <iostream>
#include <iomanip> //setw的头文件
#include <unistd.h> //usleep()的头文件,对应参数单位为微秒
#include <cstdio>
using namespace std;
int main()
{
int n = 10;
while (n >= 0) {
cout << left << setw(2) << n << '\r'; //跟C语言中printf("%-2d\r", n)效果一样
fflush(stdout); //强制刷新输出缓冲区
n--;
usleep(500000); //这里我们控制缓冲时间为0.5秒
}
cout << endl;
return 0;
}
下一步,要思考进度条的框架设计。这里的进度条将外围用 " = " 表示进度的加载,外围设置了百分比显示加载数据。用 "|/-\" 来表示其中的加载,即顺时针旋转。
2,进度条的版本一
首先,外面设置一个头文件 "process.h" 进行必要的设置
#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
using namespace std;#define Body '=' //使用body来表示进度
#define Head '>' //Head表示目前加载的终点,这里用 ' > ' 表示void process1(); //进度条函数
下面,进行进度功能的编写。这里使用 usleep 功能来控制进度的的运行,这里需注意的是输出缓冲区的刷新。
void process1()
{//用lable表示进度条的加载
string lable("|/-\\");
string nums;
int count = 0;
int lablesize = lable.size();
nums.push_back(Head);
while (count <= 100)
{
cout << "[" << left << setw(100) << nums << "]";
cout << "[" << "%" << count << "]";
cout << "[" << lable[count % lablesize] << "]" << '\r';
fflush(stdout);
nums.clear();
count++;
nums.append(count, Body);
if (count < 100)
{
nums.push_back(Head);
}//这里我们设置每0.6秒加载一次
usleep(60000);
}
cout << endl;
}
运行最终结果:
[====================================================================================================][%100][|]
3,进度条的版本二
进度条一般都是运用在一种应用上,表示应用的加载过程。很显然,版本一的进度条只是无脑运行,不知道程序进度是多少,即没有依附应用进度,比如下载程序,这时的进度条需依附于下载进度来跟进。
头文件 "process.h" 添加如下:
#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
using namespace std;#define Body '='
#define Head '>'
#define Max 103
#define FileSize 1024*1024*1024 //设置FileSize文件内存为1G,表示下载程序的总大小typedef void (*callback_t)(double); //利用函数指针来进行封装进度运用
void download(callback_t); //模拟一种下载进度
void process2(double rate); //进度条跟进程序
这里,在设置download下载时要将每一次的下载进度传递给进度条让其显示百分比。
void download(callback_t cb) //利用回调函数的形式设置进度
{
srand(time(0)*1024);
int total = FileSize;
while (total)
{
//下面表示一次下载动作
usleep(10000);
int one = rand() % (1024 * 1024 * 5);
total -= one;
if (total < 0)
{
total = 0;
}
//表示当前的进度
int download = FileSize - total;
double rate = (download * 1.0 / (FileSize)) * 100.0;
cb(rate); //每一次进度条的传递
}
}
进度条设置时要说明以下几点:
1,我们使用 "|/-\\" 表示进度跟进时是根据下载进度进行的,与当前的进度无关。
2,进度条的总设置需与下载程序紧紧联系。比如当程序加载完时,“ > ” 进度条中表示进 度运行的就要停止,即删除。
3,在输出进度运行过程,我们可添加其色彩表示美观,链接:色彩文本的增添
void process2(double rate)
{//用lable表示下载任务一直在跟进
string lable("|/-\\");//注意,这里要保留之前的进度,需设置静态
static char buffer[Max] = { 0 };
static int cnt = 0;
if (rate <= 1.0)
{
buffer[0] = Head;
}
printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]); //设置色彩,这里我们设置高亮/加粗,青色背景,红色字体的色彩
fflush(stdout);//下面控制进度的跟进
buffer[(int)rate] = Body;
if ((int)rate + 1 < 100)
{
buffer[(int)(rate + 1)] = Head;
}
if (rate >= 100.0)
{
cout << endl;
}
cnt++;
cnt %= lable.size();
}
总代码如下:
#include "process.h"
//版本一
void process1()
{string lable("|/-\\");string nums;int count = 0;int lablesize = lable.size();nums.push_back(Head);while (count <= 100){cout << "[" << left << setw(100) << nums << "]";cout << "[" << "%" << count << "]";cout << "[" << lable[count % lablesize] << "]" << '\r';fflush(stdout);nums.clear();count++;nums.append(count, Body);if (count < 100){nums.push_back(Head);}usleep(60000);}cout << endl;
}
//版本二
void download(callback_t cb)
{srand(time(0) * 1024);int total = FileSize;while (total){usleep(10000);int one = rand() % (1024 * 1024 * 5);total -= one;if (total < 0){total = 0;}int download = FileSize - total;double rate = (download * 1.0 / (FileSize)) * 100.0;cb(rate);}
}
void process2(double rate)
{static string lable("|/-\\");static char buffer[Max] = { 0 };static int cnt = 0;if (rate <= 1.0){buffer[0] = Head;}printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]);fflush(stdout);buffer[(int)rate] = Body;if ((int)rate + 1 < 100){buffer[(int)(rate + 1)] = Head;}if (rate >= 100.0){cout << endl;}cnt++;cnt %= lable.size();
}
int main()
{//process1(); //使用进度条粗略版本一download(process2); //使用进度条进化版本二return 0;
}
最后,要说明的是,以上程序都是在Linux系统下运行进行的,在VS或其它编译器下可能会出现错误消息,这时因为不同平台支持的C标准或系统设置不同而造成的差异。
相关文章:
【Linux系统编程】进度条的编写
目录 一,进度条的必备知识 1,缓冲区的粗略介绍 2,回车与换行 二,进度条的初步制作 1,进度条的初步矿建 2,进度条的版本一 3,进度条的版本二 一,进度条的必备知识 1ÿ…...
互斥锁的原理
互斥锁(Mutex,全称Mutual Exclusion)是一种同步机制,用于确保在任意时刻,只有一个线程可以访问共享资源,从而防止数据竞争和不一致性。互斥锁的基本思想是在进入临界区之前,先获取锁;…...
Win10的SVN Adapter V1.0 中黄色感叹号 -- 解决
大部分都问题都可以通过: 关闭 SVN Adapter V1.0 在下载最新的 SVNDrv.sys替换 C:\Windows\System32\drivers 中的同名文件启动 SVN Adapter V1.0 就能成功 但是部分人的电脑 SVN Adapter V1.0 是有感叹号的,说明注册表有问题 先用 CCleaner 修复注册表…...
ubuntu20 安装docker
一.官网安装文档 (基本按官方文档安装) Install Docker Engine on Ubuntu | Docker Docs 二.安装步骤 1.docker 需要64位操作系统、linux内核要在3.1以上 #uname -r 2.卸载可能存在的旧版本 #sudo apt-get remove docker docker-engine docker-ce …...
HarmonyOS开发工具DevEco Studio的下载和安装
一、DevEco Studio概述 一、下载安装鸿蒙应用开发工具DevEco Studio 开发鸿蒙应用可以从鸿蒙系统上运行第一个程序Hello World开始。 为了得到这个Hello World,你需要得到这个Hello World的源代码,源代码是用人比较容易看得懂的计算机编程语言规范写的…...
SHELL21 格式化输出
awk BEGIN{FS""}{for(i1;i<NF;i){if((NF-i)%30&&i!NF) printf $i",";else printf $i};printf "\n"} nowcoder.txt这个 AWK 命令的目的是对文本文件 nowcoder.txt 中的每一行进行处理,将每三个字符插入一个逗号,…...
披荆斩棘的「矿区无人驾驶」,能否真正打开千亿级市场?
随着2022年备受瞩目的台泥句容矿无人驾驶运输项目硬核落地,以及相关科技公司开放该矿24小时无人矿卡生产运营直播以证明其项目并非在演示,2023年全国开启了大规模矿区无人驾驶商业化落地,堪称矿区无人驾驶元年。虽然我国矿区无人驾驶市场渗透…...
智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于灰狼算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.灰狼算法4.实验参数设定5.算法结果6.参考文献7.MA…...
论文阅读三——端到端的帧到凝视估计
论文阅读三——端到端的帧到凝视估计 主要内容研究问题文章的解题思路文章的主要结构 论文实验关于端到端凝视估计的数据集3种基线模型与EFE模型的对比在三个数据集中与SOTA进行比较 问题分析重要架构U-Net 基础知识 主要内容 文章从端到端的方法出发,提出了根据he…...
mysql 快捷登陆
要将 MySQL 的登录命令添加到环境变量中并为其创建别名,可以按照以下步骤进行操作: 1. 打开终端并编辑 /etc/profile 文件(使用所有用户的全局设置) vim /etc/profile 2. 在文件的末尾添加以下行来设置环境变量和别名 # 将 &q…...
理解排序算法:冒泡排序、选择排序与归并排序
简介: 在计算机科学中,排序算法是基础且重要的概念。本文将介绍三种常见的排序方法:冒泡排序、选择排序和归并排序。我们将探讨它们的工作原理、特点和适用场景,以帮助读者更好地理解和选择合适的排序方法。 冒泡排序 冒泡排序是…...
算法-02-排序-冒泡插入选择排序
一般最经典的、最常用的:冒泡排序、插入排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。那么我们如何分析一个"排序算法"呢? 1-分析排序算法要点 时间复杂度:具体是指最好情况、最坏情况、平均情况下的时间复杂…...
流量异常-挂马造成百度收录异常关键词之解决方案(虚拟主机)
一.异常现象:流量突然暴涨,达到平时流量几倍乃至几十倍,大多数情况下因流量超标网站被停止。 二.排查原因: 1.首先分析web日志:访问量明显的成倍、几十倍的增加;访问页面不同;访问IP分散并不固…...
磁力计LIS2MDL开发(1)----轮询获取磁力计数据
磁力计LIS2MDL开发.1--轮询获取磁力计数据 概述视频教学样品申请源码下载通信模式速率生成STM32CUBEMX串口配置IIC配置CS设置串口重定向参考程序初始换管脚获取ID复位操作BDU设置设置速率启用偏移消除开启温度补偿设置为连续模式轮询读取数据主程序演示 概述 本文将介绍如何使…...
C++学习笔记—— C++内存管理方式:new和delete操作符进行动态内存管理
系列文章目录 http://t.csdnimg.cn/d0MZH 目录 系列文章目录http://t.csdnimg.cn/d0MZH 比喻和理解a.比喻C语言开空间C开空间 b.理解a、C语言的内存管理的缺点1、开发效率低(信息传递繁琐)2、可读性低(信息展示混乱)3、稳定性差&…...
8、操作符重载
友元 可以通过friend关键字,把一个全局函数、另一个类的成员函数或者另一个类整体,声明为授权类的友元友元拥有访问授权类任何非公有成员的特权友元声明可以出现在授权类的公有、私有或者保护等任何区域且不受访问控制限定符的约束友元不是成员…...
前端组件库开发
通常我们会使用很多组件库,有时候我们会去看源码比如element,antd,然后发现多少是按需导出,和vue.use全局注册,依赖于框架的拓展。 组件库的开发依赖框架的版本和node的版本,这个是需要说明的,然…...
自定义日志打印功能--C++
一、介绍 日志是计算机程序中用于记录运行时事件和状态的重要工具。通过记录关键信息和错误情况,日志可以帮助程序开发人员和维护人员追踪程序的执行过程,排查问题和改进性能。 在软件开发中,日志通常记录如下类型的信息: 事件信…...
gitlab注册无中国区电话验证问题
众所周知gitlab对中国区不友好,无法直接注册,页面无法选择86的手机号进行验证码发送。 Google上众多的方案是修改dom,而且时间大约是21年以前。 修改dom,对于现在的VUE、React框架来说是没有用的,所以不用尝试。 直接看…...
【JAVA基础题目练习】----第二天
JAVA基础题目练习 1. 键盘录入数据,比较大小2. 代码重构(简化代码,少做判断)3. 键盘录入月份的值,输出对应的季节4. 获取三个数据中的最大值使用IF语句5. 用switch语句实现键盘录入月份,输出对应的季节6. 求…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
第25节 Node.js 断言测试
Node.js的assert模块主要用于编写程序的单元测试时使用,通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试,通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词
Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵,其中每行,每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid,其中有多少个 3 3 的 “幻方” 子矩阵&am…...
