Linux 实现打印彩色进度条

文章目录

    • 预备知识
      • 一、理解回车换行
      • 二、认识行缓冲
      • 1、代码一、二(回车换行理解)
      • 2、代码三、四(sleep函数和ffush函数理解)
    • 三、简单倒计时
      • 1. 倒计时代码
      • 2、效果展示
    • 四、进度条
      • 1、效果展示
      • 2、进度条代码
        • makefile
        • ProcessBar.h
        • ProcessBar.c
        • main.c
      • 3、实现过程分析
        • 4.3.1 进度条实现样式
        • 4.3.2 进度条实现方法

预备知识

一、理解回车换行

  • 在我们熟悉的C语言中,换行就可以跳转的下一行开头 ,但其实这一操作有两个步骤,\r (回车)和 \n(换行)
  • 也就是先回到开头,再进行换行

\r 回车就是回到这一行开头
\n 换行就是另起一行

二、认识行缓冲

  • 在内存中预留了一块空间,用来缓冲输入或输出的数据,这个保留的空间被称为缓冲区。
  • 下面我们通过几个代码来理解一下:

1、代码一、二(回车换行理解)

代码一:

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

在这里插入图片描述

代码二:

  • 那我将这个\n换成了\r,再次打印会出现什么情况?
#include<stdio.h>int main()
{printf("hello world\r");return 0;
}

在这里插入图片描述

在这里插入图片描述

  • 发现 \n 可以打印出来,而 \r,不能打印出来,因为显示器模式是行刷新缓冲区是按行缓冲的,没有\n,就不能立即刷新。 \r 回到行首后,会进行覆盖写,shell 提示符会覆盖掉之前写的 “hello world”,如果我们在 “hello world” 不加 \r,则不会进行覆盖写,shell 提示符会顺着 “hello world” 往后写

如下:

在这里插入图片描述

2、代码三、四(sleep函数和ffush函数理解)

  • 行缓冲是缓冲区刷新策略的一种,在行缓冲模式下,当输入和输出中遇到 ‘\n’ 换行时,就会刷新缓冲区,下面我们认识头文件<unistd.h>的三个函数

sleep:Linux 下的休眠函数,单位是秒
usleep:和sleep 一样,单位ms(即10-6 m)
fflush :刷新缓冲区

代码 3:

#include<stdio.h>
#include<unistd.h>int main()
{printf("hello world");sleep(3);return 0;
}

在这里插入图片描述

  • 我们写的这个C语言程序是从上到下依次执行的,而我们看到的是先休眠后打印
  • 这是因为数据保存在缓冲区中,没有主动刷新。当程序退出后,保存在缓冲区中的数据被自动刷新出来了,如果我们想提前刷新,便可以调用fflush函数来刷新缓冲区

代码四:

#include <stdio.h>
#include <unistd.h>                                                                                                     
int main()
{printf("hello world");fflush(stdout);printf("\n");sleep(3);return 0;
}

在这里插入图片描述

  • 这次 “hello world” 被直接打印出来,我们加 \n避免shell 提示符出现在 “hello world” 后面

三、简单倒计时

1. 倒计时代码

#include <stdio.h>
#include <unistd.h>
int main()
{int cnt=10;while(cnt>=0){printf("%-2d\r",cnt);fflush(stdout);sleep(1);cnt--;                                                                                                                                            }printf("\n");return 0;
}

2、效果展示

在这里插入图片描述

具备了以上介绍的知识,接下来我们就实现进度条了

四、进度条

1、效果展示

在这里插入图片描述

2、进度条代码

makefile
processbar:ProcessBar.c main.cgcc -o $@ $^ 
.PHONY:clean
clean:  rm -rf processbar
ProcessBar.h
#pragma once
#include <string.h>
#include <unistd.h>
#include <stdio.h>// 进度条箭头
#define TAIL '>'// 进度条的数组大小
#define Length 102// 进度条加载的进度条
#define Style '='// 重定义函数指针
typedef void (*callback_t)(double, double);// 进度条的实现
void ProcBar(double total, double current);
ProcessBar.c
#include "ProcessBar.h"#define LIGHT_CYAN   "\033[1;36m" // 亮青色
#define NONE "\033[m" 	//截断// 显示进度
const char* lable = "|/-\\";void ProcBar(double total, double current)
{char bar[Length];// 初始化进度条memset(bar, '\0', sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0) / total;// 循环次数int loop_count = (int)rate;while (cnt < loop_count){bar[cnt++] = Style;if (rate < 100)bar[loop_count] = TAIL;}// 打印显示printf(LIGHT_CYAN"[%-100s]"NONE"[%.2lf%%][%c]\r", bar, rate, lable[cnt % len]);// 刷新缓冲区fflush(stdout);
}
main.c
#include "ProcessBar.h"// 网络带宽【1mb】
double bandwidth = 1024 * 1024 * 1.0;void download(double filesize, callback_t cb)
{//  累计下载的数据量double current = 0.0;printf("download begin, current: %lf\n", current);while (current <= filesize){// 使用函数指针更新界面cb(filesize, current);//从网络中获取数据//......// 睡眠usleep(100000);// 累计下载current += bandwidth;}printf("\ndownload done, filesize: %lf\n", filesize);
}int main()
{// 测试调用//download(100 * 1024 * 1024, ProcBar);download(2 * 1024 * 1024, ProcBar);//download(200*1024*1024,ProcBar);//download(400*1024*1024,ProcBar);download(50*1024*1024,ProcBar);download(10*1024*1024,ProcBar);// 测试//ProcBar(100.0, 56.9);//ProcBar(100.0, 1.0);//ProcBar(100.0, 99.9);//ProcBar(100.0, 100);return 0;
}

3、实现过程分析

4.3.1 进度条实现样式

进度条样式 :

  • 进度条的主要内容是两个中括号包裹,中间进度显示以=>的方式进行推进呈现

进度条百分比:

  • 显示当前进度百分比,随着进度不断推进,百分比也在增加

进度条旋转字符:

  • 显示加载样式,可以利用一个旋转的字符,例如 [] 的样式,顺时针不断旋转,依次为 “| / - \”,注意 ** 也是转义字符,因此需要两个 *\ *

进度条颜色:

c语言颜色参考
我们可以根据自己的喜好给进度条上色,在此我们找到颜色参照表

4.3.2 进度条实现方法
  • 预留进度条大小为 100 个 = ,外加 1 个 > ,加上保存 \0 的位置,定义一个102个单位的长度的bar数组。

  • 如果将打印放在循环中的话,在打印的时候会变得卡卡的,我们可以将打印放到循环外面,等数组放上=>后,在一起打印,这样更好

  • 我们又实现了一个函数download(),把ProcBar(),作为参数传递给download(),用usleep函数模拟下载时间,然后循环起来回调processbar()函数,便实现了进度条

  • 最后考虑到第二次下载,bar数组满了,我们再每次调用download()函数时,清空bar数组,完成实现~~

  • 这就实现了我们最终的效果

在这里插入图片描述

最后本文就到这里结束了,感谢大家的收看,请多多指点~

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端如何上传图片给后台?如何传递 multipart/form-data 类型的数据?图片大小、格式检查?

1. 如何上传图片&#xff1f; 图片上传需要传二进制流&#xff0c;请求头的 content-type 类型需为 multipart/form-data&#xff0c;传递的格式如下图所示 前后端交互通常为&#xff1a; 先调用接口上传二进制流图片然后再上传表单其他内容&#xff08;第一步通常会返回后台…

从 HPC 到 AI:探索文件系统的发展及性能评估

随着 AI 技术的迅速发展&#xff0c;模型规模和复杂度以及待处理数据量都在急剧上升&#xff0c;这些趋势使得高性能计算&#xff08;HPC&#xff09;变得越来越必要。HPC 通过集成强大的计算资源&#xff0c;比如 GPU 和 CPU 集群&#xff0c;提供了处理和分析大规模数据所需的…

Canvas笔记04:绘制九大基本图形的方法,重头戏是贝塞尔曲线

hello&#xff0c;我是贝格前端工场&#xff0c;最近在学习canvas&#xff0c;分享一些canvas的一些知识点笔记&#xff0c;本期分享canvas绘制图形的知识&#xff0c;欢迎老铁们一同学习&#xff0c;欢迎关注&#xff0c;如有前端项目可以私信贝格。 Canvas是HTML5中的一个绘…

1分钟帮你快速搞定遥测终端机RTU选型!

遥测终端机RTU-MGTR-W系列 精准应对贴心服务每一个关键场景 MGTR-W系列遥测终端机在水利水务领域有着广泛的应用&#xff0c;能够满足各种细分场景的需求。该系列终端机助力实现灌区信息化、高标准农田建设、农村供水信息化、水库雨水情监测、大坝安全监测、地下水监测以及水…

使用Python来发送电子邮件(手把手教学)

一、首先得准备两个邮箱 1、接收邮箱地址随意&#xff08;可以再添加一个QQ邮箱做接收用&#xff09;&#xff0c; 2、重点是发送邮箱&#xff0c;发送邮箱这里使用的是QQ邮箱&#xff1a; ① 打开一个web&#xff0c;登录QQ邮箱&#xff1a; 右上角&#xff1a; ②安全设置-…

如何恢复edge的自动翻译功能

介绍&#xff1a;对于英文不好的小伙伴&#xff0c;把英语翻译成中文是有帮助的&#xff0c;而edge可以直接对英文页面翻译这一功能更是受人喜爱&#xff0c;但是&#xff0c;最近发现这一项功能消失了。 原始界面&#xff1a; 下面展示如何恢复该功能。 1.打开edge&#xff…

JavaScript实现遍历精灵图的效果

问题描述&#xff1a;通过JavaScript将精灵图里面的小图标给遍历出来。 关键代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width…

安全测试:抵御现代网络威胁的盾牌!

什么是安全测试 安全测试是软件测试的一个重要方面&#xff0c;专注于识别和解决软件应用程序中的安全漏洞。它旨在确保软件免受恶意攻击&#xff0c;未经授权的访问和数据泄露。 安全测试的目的 安全测试涉及核实软件是否符合安全标准&#xff0c;评估安全功能和机制&#…

【b站咸虾米】ES6 Promise的用法,ES7 async/await异步处理同步化,异步处理进化史

课程地址&#xff1a;【ES6 Promise的用法&#xff0c;ES7 async/await异步处理同步化&#xff0c;异步处理进化史】 https://www.bilibili.com/video/BV1XW4y1v7Md/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 图文地址&#xff1a;https://www.b…

Selenium自动化测试-3.元素定位(2)

我们发现网站并没有id、name等属性。那么&#xff0c;我们可以用更高级的定位方法——xpath来定位元素。 什么是xpath? xpath是一种在XML文档中定位元素的语言。因为HTML可以看做XML的一种实现&#xff0c;所以selenium用户可以使用这种强大语言在web应用中定位元素&#xf…

基于单片机的智能空调设计

目 录 摘 要 I Abstract II 引 言 1 1 系统整体设计 3 1.1 系统方案设计 3 1.2 系统工作原理 3 2 硬件设计 5 2.1 电源模块设计 5 2.1.1 电源模块选择 5 2.1.2 电源模块电路设计 5 2.2 单片机模块设计 5 2.2.1 单片机型号选择 5 2.2.2 单片机模块电路设计 6 2.3 按键模块设计 …

高质量的外贸开发信标题都是怎样的?

今天在网上看到很多不错的开发信标题&#xff0c;觉得不错&#xff0c;收藏起来分享给大家学习。 标题是吸引读者打开邮件的第一印象&#xff0c;对于外贸销售人员来说&#xff0c;精心撰写开发信标题至关重要。客户收到的邮件那么多&#xff0c;那么在客户收件箱中的5至20个客…