【Linux】Linux进度条小程序(包含色块实现)

我们再将Linux常用工具与命令都学会了之后,
设计进度条这个小程序可以比较好的帮助我们进行一定程度练习与巩固

目录

  • 预备知识:
    • 回车换行:
    • 缓冲区:
  • 进度条:
    • 准备工作:
    • 主题思路:
    • 代码实现:
    • 模拟实际场景:
    • 关于色块:
  • 完整代码:

预备知识:

在开始之前我们需要有两个预备知识,可以更好的辅助我们进行设计程序。

回车换行:

我们经常说的回车换行其实是两个概念

回车
代表从你现在的位置到你本行起始的位置,转义字符为'\r'
在这里插入图片描述


换行:
仅仅只是从本行的当前位置到移动到下一行。一般没有此操作的转义字符,大多数情况下都是'\n'既包括了换行与回车;
在这里插入图片描述


缓冲区:

我们先运行如下代码:

#include <stdio.h>
int main()
{
	printf("hello Makefile!\n");
	sleep(3);
	return 0;
}

发现终端会停止3s在出现hello Makefile!字符串,
这也就说明了缓冲区的存在在,
但是现阶段我们是很难对缓冲区有深刻理解的,
只需要知道他的存在会造成什么影响即可

缓冲区是内存中的一段空间,当程序结束或者遇到'\n'时会刷新缓冲区,
也可以选择使用fflush(stdout)进行主动刷新缓冲区

证明方法:

#include <stdio.h>
int main()
{
	printf("hello Makefile!");
	fflush(stdout);
	sleep(3);
	return 0;
}

我们在sleepfflush进行刷新即可发现结论成立


进度条:

进度条是个比较简单的小程序,有了大概得思想,实现起来细心一点是没什么大问题的。

准备工作:

此准备工作非预备工作,
这部分主要是构建makefile方便我们进行自动构建
首先还是老样子,touch上3个文件,进行声明与定义分离,还有个main文件
在这里插入图片描述
在makefile中进行配置。

在这里插入图片描述

主题思路:

每次打印时实际上都对上一次打印的数据进行覆盖,
并且每一次打印的数据都是根据当前进度进而改变进度条增加的长度。
在这里插入图片描述
我们打算搞一个如上图的进度条

代码实现:

有了预备知识作为铺垫,思想也有了,代码还是信手拈来的

注意
此时我们并不是仿真,而是先设计一个进度条框架,随后再进行仿真设计

#define length 101
#define style '-'
const char* table = "-\\|/";

void ProgBar()                                                                                                                      
{
    char str[length] = {0};
    int count = 0;
    while(count <= 100)
    {
        printf("[%-100s][%d%%][%c]\r", str, count, table[count%4]);
        fflush(stdout);
        str[count++] = style;
        usleep(50000);
    }
    printf("\n");
}

模拟实际场景:

也不是完全的模拟,只是我们自己设置了带宽与总大小,得到一个相对应的比例,没有将带宽设置随机

可以在Main文件中造一个模拟下载的环境,同时使用回调函数的方式进行传参

double bandwidth = 1024*1024*1.0;

void download(double filesize, back_t func)
{
    printf("download begin filesize:%lf\n", filesize);
    double current = 0;
    while(current <= filesize)
    {
        func(filesize, current);
        current += bandwidth;
        usleep(50000);
    }
    printf("\ndownload down filesize:%lf", filesize);
    printf("\n");
}

int main()
{
	//博主用来测试的函数
    download(1024*1024*10, ProgBar);
    download(1024*1024*90, ProgBar);
    download(1024*1024*60, ProgBar);
    download(1024*1024*40, ProgBar);
    return 0;
}

将定义文件中的函数进行一些微调

#define length 101
#define style '-'
const char* table = "-\\|/";

void ProgBar(double total, double current)
{
    char str[length] = {0};
    int count = 0;
    int len = strlen(table);
    double rate = (current / total)*100;

    while(count <= (int)rate)
    {
        str[count++] = style;
    }
    printf("[%-100s][%.2lf%%][%c]\r", str, rate, table[count%len]);
    fflush(stdout);
}

声明文件中:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include"color.h"

void ProgBar(double total, double current);
//回调函数的声明
typedef void (*back_t)(double, double);

关于色块:

关于色块博客链接,这里介绍了如何输出的用法,博主是直接粘贴过来缝缝补补直接用上了

代码实现基本逻辑是一致的,无非是变成了多次输出才形成一个完整的进度条

//version1 color
void ProgBar()
{
    char flag[] = {'-', '\\', '|', '/'};
    int len = strlen(flag);

    int i = 0;
    int j = 0;
    int cnt = 0;
    while(cnt <= 100)
    {
        i = cnt;
        j = 100 - cnt;
        //这段i的while循环就是生成色块的关键,其中的reverse是宏定义
        while(i--)
        {
            printf(REVERSE " " NONE);
        }
        while(j--)
        {
            printf(" ");
        }
        printf("[%d%%][%c]\r", cnt, flag[cnt%len]);
        cnt++;
        fflush(stdout);
        usleep(50000);
    }
    printf("\n");
}

这是宏定义的代码(上边放的博客链接有具体的):

#define NONE                  "\e[0m"           //清除颜色,即之后的打印为正常输出,之前的不受影响
#define BLACK                 "\e[0;30m"         //深黑
#define L_BLACK             "\e[1;30m"            //亮黑,偏灰褐
#define RED                     "\e[0;31m"      //深红,暗红
#define L_RED                 "\e[1;31m"        //鲜红
#define GREEN                "\e[0;32m"         //深绿,暗绿
#define L_GREEN            "\e[1;32m"           //鲜绿
#define BROWN               "\e[0;33m"          //深黄,暗黄
#define YELLOW              "\e[1;33m"          //鲜黄
#define BLUE                    "\e[0;34m"      //深蓝,暗蓝
#define L_BLUE                "\e[1;34m"        //亮蓝,偏白灰
#define PURPLE               "\e[0;35m"         //深粉,暗粉,偏暗紫
#define L_PURPLE           "\e[1;35m"           //亮粉,偏白灰
#define CYAN                   "\e[0;36m"       //暗青色
#define L_CYAN               "\e[1;36m"         //鲜亮青色
#define GRAY                   "\e[0;37m"       //灰色
#define WHITE                  "\e[1;37m"       //白色,字体粗一点,比正常大,比bold小
#define BOLD                    "\e[1m"         //白色,粗体
#define UNDERLINE         "\e[4m"               //下划线,白色,正常大小
#define BLINK                   "\e[5m"         //闪烁,白色,正常大小
#define REVERSE            "\e[7m"              //反转,即字体背景为白色,字体为黑色
#define HIDE                     "\e[8m"        //隐藏
#define CLRLINE               "\r\e[K"          //清除行

完整代码:

ProgressBar.h:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include"color.h"
//void ProgBar();

void ProgBar(double total, double current);
typedef void (*back_t)(double, double);

ProgressBar.c(有注释说明对应哪个版本):
version 1:无仿真
version 2:仿真
version 1 color:无仿真
version 2 color:仿真

#include"ProgressBar.h"

#define length 101
#define style '-'
const char* table = "-\\|/";
//version 1 no color
void ProgBar()
{
    char str[length] = {0};
    int count = 0;
    while(count <= 100)
    {
        printf("[%-100s][%d%%][%c]\r", str, count, table[count%4]);
        fflush(stdout);
        str[count++] = style;
        usleep(50000);
    }
    printf("\n");
}

//version 2 no color
//void ProgBar(double total, double current)
//{
//    char str[length] = {0};
//    int count = 0;
//    int len = strlen(table);
//    double rate = (current / total)*100;
//
//    while(count <= (int)rate)
//    {
//        str[count++] = style;
//    }
//    printf("[%-100s][%.2lf%%][%c]\r", str, rate, table[count%len]);
//    fflush(stdout);
//}

//version1 color
//void ProgBar()
//{
//    char flag[] = {'-', '\\', '|', '/'};
//    int len = strlen(flag);
//
//    int i = 0;
//    int j = 0;
//    int cnt = 0;
//    while(cnt <= 100)
//    {
//        i = cnt;
//        j = 100 - cnt;
//        while(i--)
//        {
//            printf(REVERSE " " NONE);
//        }
//        while(j--)
//        {
//            printf(" ");
//        }
//        printf("[%d%%][%c]\r", cnt, flag[cnt%len]);
//        cnt++;
//        fflush(stdout);
//        usleep(50000);
//    }
//    printf("\n");
//}

//version2 color
//void ProgBar(double total, double current)
//{
//    double rate = current*100/total;
//
//    int i = 0;
//    int j = 0;
//    int cnt = (int)rate;
//
//    i = cnt;
//    j = 100 - cnt;
//    while(i--)
//    {
//        printf(REVERSE " " NONE);
//    }
//    while(j--)
//    {
//        printf(" ");
//    }
//    printf("[%.2lf%%][%c]\r", rate, table[cnt%4]);
//    fflush(stdout);
//}

Main.c:

#include"ProgressBar.h"

double bandwidth = 1024*1024*1.0;

void download(double filesize, back_t func)
{
    printf("download begin filesize:%lf\n", filesize);
    double current = 0;
    while(current <= filesize)
    {
        func(filesize, current);
        current += bandwidth;
        usleep(50000);
    }
    printf("\ndownload down filesize:%lf", filesize);
    printf("\n");
}

int main()
{
    download(1024*1024*10, ProgBar);
    download(1024*1024*90, ProgBar);
    download(1024*1024*60, ProgBar);
    download(1024*1024*40, ProgBar);
    //ProgBar();
    //ProgBar(100, 59.9);
    return 0;
}

color.h

#define NONE                  "\e[0m"           //清除颜色,即之后的打印为正常输出,之前的不受影响
#define BLACK                 "\e[0;30m"         //深黑
#define L_BLACK             "\e[1;30m"            //亮黑,偏灰褐
#define RED                     "\e[0;31m"      //深红,暗红
#define L_RED                 "\e[1;31m"        //鲜红
#define GREEN                "\e[0;32m"         //深绿,暗绿
#define L_GREEN            "\e[1;32m"           //鲜绿
#define BROWN               "\e[0;33m"          //深黄,暗黄
#define YELLOW              "\e[1;33m"          //鲜黄
#define BLUE                    "\e[0;34m"      //深蓝,暗蓝
#define L_BLUE                "\e[1;34m"        //亮蓝,偏白灰
#define PURPLE               "\e[0;35m"         //深粉,暗粉,偏暗紫
#define L_PURPLE           "\e[1;35m"           //亮粉,偏白灰
#define CYAN                   "\e[0;36m"       //暗青色
#define L_CYAN               "\e[1;36m"         //鲜亮青色
#define GRAY                   "\e[0;37m"       //灰色
#define WHITE                  "\e[1;37m"       //白色,字体粗一点,比正常大,比bold小
#define BOLD                    "\e[1m"         //白色,粗体
#define UNDERLINE         "\e[4m"               //下划线,白色,正常大小
#define BLINK                   "\e[5m"         //闪烁,白色,正常大小
#define REVERSE            "\e[7m"              //反转,即字体背景为白色,字体为黑色
#define HIDE                     "\e[8m"        //隐藏
#define CLRLINE               "\r\e[K"          //清除行

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

腾讯云服务器上发送邮件连接超时

腾讯云会将服务器25端口禁用&#xff08;腾讯云默认禁用&#xff09;&#xff0c;开启后发送正常 https://console.cloud.tencent.com/secctrl 参考 腾讯云服务器上发送邮件连接超时&#xff08;无法发送&#xff09;的相关问题

spring-boot-starter-validation常用注解

文章目录 一、使用二、常用注解三、Valid or Validated &#xff1f;四、分组校验1. 分组校验的基本概念2. 定义验证组3. 应用分组到模型4. 在控制器中使用分组5. 总结 一、使用 要使用这些注解&#xff0c;首先确保在你的 Spring Boot 应用的 pom.xml 文件中添加了 spring-bo…

使用EtherNET转Profinet网关配置EtherNET/IP地址说明

EtherNET转Profinet网关配置EtherNET/IP地址是将两种网络之间的连接进行设置和调整&#xff0c;以便实现数据的传输和信息的交互。这个过程中&#xff0c;需要对EtherNET/IP地址进行配置&#xff0c;以确保数据能够正确地在网络之间传递。通过配置EtherNET/IP地址&#xff0c;可…

vue2(Vuex)、vue3(Pinia)、react(Redux)状态管理

vue2状态管理Vuex Vuex 是一个专为 Vue.js应用程序开发的状态管理模式。它使用集中式存储管理应用的所有组件的状态&#xff0c;以及规则保证状态只能按照规定的方式进行修改。 State&#xff08;状态&#xff09;:Vuex 使用单一状态树&#xff0c;即一个对象包含全部的应用层…

sql管理工具archery简介

在平时的工作过程中&#xff0c;我们肯定会遇到使用sql平台的场景&#xff0c;业内也有很多工具&#xff0c;类似阿里云的dms&#xff0c;但是这个是和云厂商绑定的&#xff0c;我们可能一般没有用到阿里云组件就比较困难了&#xff0c;那还有什么选项了&#xff0c;经过调研&a…

JVM简介

一、什么是JVM JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组…

YOLOv5全网独家首发:Powerful-IoU更好、更快的收敛IoU,效果秒杀CIoU、GIoU等 | 2024年最新IoU

💡💡💡本文独家改进:Powerful-IoU更好、更快的收敛IoU,是一种结合了目标尺寸自适应惩罚因子和基于锚框质量的梯度调节函数的损失函数 💡💡💡MS COCO和PASCAL VOC数据集实现涨点 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_1251193…

哪些 3D 建模软件值得推荐?

云端地球是一款免费的在线实景三维建模软件&#xff0c;不需要复杂的技巧&#xff0c;只要需要手机&#xff0c;多拍几张照片&#xff0c;就可以得到完整的三维模型&#xff01; 无论是大场景倾斜摄影测量还是小场景、小物体建模&#xff0c;都可以通过云端地球将二维数据向三…

C++哈希表模拟实现unordered_map 与unordered_set

哈希概念 unordered系列的关联式容器&#xff08;如unordered_map unordered_set&#xff09; 之所以效率比较高&#xff0c;是因为其底层使用了哈希结构 顺序结构以及平衡树 中&#xff0c;元素关键码与其存储位置之间没有对应的关系&#xff0c;因此在 查找一个元素 时&am…

php二次开发股票系统代码:腾讯股票数据接口地址、批量获取股票信息、转换为腾讯接口指定的股票格式

1、腾讯股票数据控制器 <?php namespace app\index\controller;use think\Model; use think\Db;const BASE_URL http://aaaaaa.aaaaa.com; //腾讯数据地址class TencentStocks extends Home { //里面具体的方法 }2、请求接口返回内容 function juhecurl($url, $params f…

Linux/Uinx 系统编程:进程管理(1)

Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;1&#xff09; 文章目录 Linux/Uinx 系统编程&#xff1a;进程管理&#xff08;1&#xff09;什么是进程进程来源INIT 和 守护进程登录进程sh进程进程的执行模式进程管理的系统调用关于syscall中参数b&#xff0c;c&#x…

HCIP 三层交换

拓扑图&IP划分如下&#xff1a; 第一步&#xff0c;配置IP 以R1为例&#xff0c;R2同理 LSW1&#xff0c;LSW2同理 第二步&#xff0c;聚合链路 LSW1&#xff0c;LSW2同理 修改串口 LSW1&#xff0c;LSW2同理 第三步&#xff0c;配置生成树 LSW1&#xff0c;LSW2同理 …

听力下降为什么会影响到言语感知?

一、听力障碍对阈值、听觉频率范围和分辨能力的影响 听力障碍使得听障者的听敏度降低&#xff0c;提高了阈值&#xff0c;不利于言语信号的接收。听障者听力阈值的变化在不同频率并不相同&#xff0c;一般而言&#xff0c;高频部分的听力损失往往大于低频部分&#xff0c;而言…

代码随想录刷题笔记-Day11

1. 逆波兰表达式求值 150. 逆波兰表达式求值https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/ 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&a…

区块链技术在教育领域的应用:Web3教育变革

随着Web3时代的来临&#xff0c;区块链技术在各个领域都展现出了巨大的潜力&#xff0c;而在教育领域&#xff0c;区块链的应用正引领着一场教育变革。本文将深入探讨区块链技术在教育领域的创新应用&#xff0c;以及这一应用如何推动Web3时代的教育变革。 1. 学历和成绩的去中…

Shell脚本⑤函数与数组

一.函数 封装的可重复利用的具有特定功能的代码 格式&#xff1a; 方法一&#xff1a; [function] 函数名 (){ 命令序列 [return x] #使用return或者exit可以显式的结束函数 } 方法二&#xff1a; 函数名(){ 命令序列 } 1.函数的调用方法 &#xff08;1&…

【K8S 云原生】K8S的安全机制

目录 一、K8S安全机制概述 1、概念 2、请求apiserver资源的三个步骤&#xff1a; 一、认证&#xff1a;Anthentcation 1、认证的方式&#xff1a; 1、HTTP TOKEN&#xff1a; 2、http base&#xff1a; 3、http证书&#xff1a; 2、认证的访问类型&#xff1a; 3、签发…

【Power Platform】实现让审批人可以修改其他人提交的表单中的部分字段

之前我们分享的案例里&#xff0c;我提了一嘴我们的客户有一个需求&#xff0c;就是审批人要有能力修改其他人表单中的部分字段。 今天我们就来分享一下如何实现这个功能。 要实现这个效果&#xff0c;我们需要判断三个值——当前审批人是不是当前登录人、当前审批节点可以修…

基于python京东商品数据采集与可视化分析大屏设计与实现

随着电子商务行业的快速发展&#xff0c;京东作为中国最大的综合性电商平台之一&#xff0c;拥有海量的商品数据。对这些数据进行采集与分析&#xff0c;能够帮助企业了解市场趋势、消费者需求以及产品销售情况&#xff0c;为决策提供科学依据。 本文旨在基于京东商品数据的采…

Linux设备树中的 gpio 信息

一. 简介 前面几篇文章讲解了 pinctrl 子系统&#xff0c; pinctrl 子系统重点是设置 PIN( 有的 SOC 叫做 PAD) 的复用 和电气属性。 注意&#xff1a;如果 pinctrl 子系统将一个 PIN 复用为 GPIO 的话&#xff0c;那么接下来就要用到 gpio 子系统了。如果 PIN用作其他…
最新文章