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

news2024/10/2 8:19:58

我们再将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.coloradmin.cn/o/1412955.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

理想架构的Doherty功率放大器理论与仿真

Doherty理论—理想架构的Doherty功率放大器理论与仿真 参考&#xff1a; 三路Doherty设计 01 射频基础知识–基础概念 ADS仿真工程文件链接&#xff1a;理想架构的Doherty功率放大器理论与仿真 目录 Doherty理论---理想架构的Doherty功率放大器理论与仿真0、Doherty架构的作用…

Open CASCADE学习|圆柱螺旋线绘制原理探究

1、圆柱螺旋线绘制原理 在OCC中&#xff0c;圆柱面的参数方程为&#xff1a; 设P为&#xff08;x0,y0,z0&#xff09;,则 xx0r*cos(u) yy0r*sin(u) zz0v 但u、v之间有关系时&#xff0c;此方程表达为圆柱螺旋线&#xff0c;u、v之间为线性关系时是等螺距螺旋线&#xff0…

unity 装饰器模式(实例详解)

文章目录 简介1. **组件装饰器&#xff08;Component Decorators&#xff09;**:2. **游戏对象特效装饰器&#xff08;GameObject Effects Decorator&#xff09;**:3. **输入处理装饰器&#xff08;Input Handling Decorators&#xff09;**:4. **性能优化装饰器&#xff08;P…

蓝牙----蓝牙协议栈Host层

蓝牙协议栈----Host层 蓝牙物理层基本信息链路层的状态机进入连接态的步骤主动扫描与被动扫描链路层通信模式 蓝牙地址蓝牙设备地址蓝牙标识地址蓝牙接入地址 蓝牙广播信道管理蓝牙数据信道跳频 蓝牙协议栈Host层包括PHY、LL、HCL层&#xff0c;注重关注PHY物理层和LL链路层。 …

微服务入门篇:Eureka注册中心(作用,搭建Eureka客户端和服务端)

目录 1.提供者与消费者2.Eureka的作用3.搭建EurekaServer1.配置服务端2.配置客户端3.复制实例操作4.服务拉取 1.提供者与消费者 ①服务提供者:一次业务中&#xff0c;被其它微服务调用的服务。&#xff08;提供接口给其它微服务) ②服务消费者:一次业务中&#xff0c;调用其它微…

嵌入式学习-C++-Day3

嵌入式学习-CDay3 一、思维导图 二、作业 1.设计一个Per类&#xff0c;类中包含私有成员:姓名、年龄、指针成员身高、体重&#xff0c;再设计一个Stu类&#xff0c;类中包含私有成员:成绩、Per类对象p1&#xff0c;设计这两个类的构造函数、析构函数和拷贝构造函数。 #inclu…

UBUNTU中NGINX的负载均衡和环境搭建

1.准备三台ubuntu版本的虚拟机 2.开始安装&#xff0c;下载&#xff0c;解压&#xff0c;以及编译nginx所需的环境依赖 这里需要注意我们创建了一个新的目录 /home/nginx,所以在编译中记得更改 然后再编译过程中我们会发现提示无法编译&#xff0c;原因是缺少c语言的插件&…

Java 字符串 06 练习-字符串拼接、反转、金额转换(黑马)

代码&#xff1a; //import java.util.Scanner; public class practice{public static void main(String[] args) {int arr [] {1,2,3,4};String str arrToString(arr);System.out.println(str);}public static String arrToString(int [] arr){if(arrnull){return "&q…

让B端管理软件既美观又实用的解决方案来了

hello宝子们...我们是艾斯视觉擅长ui设计和前端开发10年经验&#xff01;希望我的分享能帮助到您&#xff01;如需帮助可以评论关注私信我们一起探讨&#xff01;致敬感谢感恩&#xff01; 让B端管理软件既美观又实用的解决方案来了 在当今数字化时代&#xff0c;B端管理软件已…

每日一题——LeetCode2859.计算K置位下标对应元素的和

方法一 枚举法&#xff1a; 通过不断地将目标数值与 1 进行按位与操作&#xff0c;并根据结果判断最低位是否为 1&#xff0c;从而统计其中包含的 1 的个数。 如果1的个数等于K就加上该值。 var sumIndicesWithKSetBits function(nums, k) {function countOnes(num) {let cou…

谷歌企业开发者如何申请邓白氏码?

邓白氏编码是具有唯一性的9位数标识符&#xff0c;由 Dun & Bradstreet 分配给各组织&#xff0c;用于验 证商家&#xff0c;一个公司可免费申请一个。没有邓白氏编码&#xff0c;则不能注册单位开发者账号。 申请和接收邓白氏码是无需支付任何费用的&#xff0c;全程免费…

09.Elasticsearch应用(九)

Elasticsearch应用&#xff08;九&#xff09; 1.搜索结果处理包括什么 排序分页高亮返回指定字段 2.排序 介绍 Elasticsearch支持对搜索结果排序&#xff0c;默认是根据相关度算分来排序 支持排序的字段 keyword数值地理坐标日期类型 排序语法 GET /[索引名称]/_sear…

MVC架构模式与三层架构

提示&#xff1a;博客中的图片来源于动力节点在B站的视频讲解。 MVC架构模式与三层架构 一、三层架构二、MVC&#xff08;model view controller&#xff09;1.MVC 框架的工作流程&#xff08;1&#xff09;JSP Servlet javabean实现MVC。&#xff08;2&#xff09;SSM&#…

力扣1035. 不相交的线

动态规划 思路&#xff1a; 思路同 力扣1143. 最长公共子序列假设 dp[i][j] 为 nums1 长度 i 和 nums2 长度 j 能够组成不想交线的个数&#xff1b;可知 dp[0][j] 0&#xff08;nums1 长度为 0 不能组成线&#xff09;&#xff1b;同理 dp[i][j] 0&#xff1b;转移方程&…

python就业如何?和C++相比该选择哪个更好?

python就业如何&#xff1f;和C相比该选择哪个更好&#xff1f; 在开始前我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「C的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区回复“888”之后私信回复“888”&#xff0c;全部无偿共享给大家&#xff…

202410读书笔记|《半小时漫画青春期》——成为自己世界的星星,这才是最要紧的事儿

202410读书笔记|《半小时漫画青春期&#xff1a;心理篇》——成为自己世界的星星&#xff0c;这才是最要紧的事儿 一、一到考试就焦虑&#xff0c;怎么办&#xff1f;二、以前情绪挺淡定&#xff0c;现在咋动不动就爆发&#xff1f;三、追星那么开心&#xff0c;为啥还要我小心…

CHS_07.2.2.4_3+调度算法:多级队列调度算法

CHS_07.2.2.4_3调度算法&#xff1a;多级队列调度算法 多级对列调度算法 接下来 多级对列调度算法 看一个图你就明白了 如果一个系统采用多级对列调度算法 那么 这个系统会按照进程的类型设置多个对列 并且给不同的对列设置不同的优先级 举个例子 分为系统进程 交互式进程以…

力扣算法-Day19

344.反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 你可以假设数组中的所有字符都是 ASCII 码表中的…

5|领域建模实践(上):怎样既准确又深刻地理解业务知识?

上节课咱们完成了事件风暴&#xff0c;梳理了系统的行为需求。但你可能也发现了&#xff0c;其实还有些微妙的业务概念还没有澄清&#xff0c;这就要靠领域建模来完成了。 建立领域模型是 DDD 的核心。要建好领域建模&#xff0c;需要理论和实践相结合。由于我们的模型有一定的…

5.【SpringBoot3】文件上传

1. 文件上传到本地 需求分析 在用户更换头像或发布文章时&#xff0c;需要携带一个图片的 url 地址&#xff0c;该 url 地址是当用户访问文件上传接口&#xff0c;将图片上传成功后&#xff0c;服务器返回的地址。所以&#xff0c;后台需要提供一个文件上传接口&#xff0c;用…