C语言Linux进度条模拟

        在Linux字符界面中,使用yum、apt下载东西时会有一个图形化的进度条,可以告诉我们任务的执行进度。

        我们也可以通过C语言实现一个类似的进度条,并且可以做得更加美观。以后我们自己写的程序需要显示进度时就可以去调用我们自己实现的进度条。

进度条实现

        下面这个是apt的进度条,可以看到这个进度条是通过在 [ ] 中填充 '#' 来实现的进度递增,同时还会显示当前进度的百分比。

        实际上要实现这个进度条,并不复杂。我们可以创建一个数组,每次进度递增就往里面填充 '#'。

#include <stdio.h>
#include <unistd.h>char bar[101] = ""; //100个#号,一个\0int main()
{int rate = 0;   //速率while(rate <= 100){usleep(50000)    //睡眠时间,不让进度条很快就执行完printf("[%s]\n", bar);bar[rate++] = '#';}return 0;
}

        这个程序的执行结果如下: 

        可以发现我们的进度条是打印出来了,但是还存在很多问题。首先这个进度条并不是在同一行打印出来的,并且 ']' 是紧跟最右边的 '#' 的。

        我们在打印进度条时,使用了 '\n' 换行,这是不正确的。我们应该使用 '\r' 回车。

'\n' 换行:使光标下移一格
'\r' 回车:使光标回到本行首位

        接下来,我们对代码进行改进。

#include <stdio.h>
#include <unistd.h>char bar[101] = ""; //100个#号,一个\0int main()
{int rate = 0;while(rate <= 100){usleep(50000);printf("[%-100s]\r", bar);bar[rate++] = '#';}return 0;
}

        可以看到进度条确实是在同一行执行了,但是程序打印时并没有一个一个 '#' 的进行打印。而是一段一段的。 

        这是因为缓冲区没有立刻刷新,当时使用 '\n' 没有这个问题,是因为换行时就会刷新缓冲区。但是 '\r' 回车并不会刷新缓冲区,我们想实现立刻刷新缓冲区可以使用 fflush() 函数。

#include <stdio.h>
#include <unistd.h>char bar[101] = ""; //100个#号,一个\0int main()
{int rate = 0;while(rate <= 100){usleep(50000);printf("[%-100s]\r", bar);fflush(stdout);    //stdout标准输出bar[rate++] = '#';}printf("\n");    //换行return 0;
}

         我们已经实现了一个正常的进度条了,现在可以对进度条进行美化加工,让它变得更加美观。

#include <stdio.h>
#include <unistd.h>char bar[101] = ""; //100个#号,一个\0
char* table = "|/-\\";int main()
{int rate = 0;while(rate <= 100){usleep(50000);printf("[%-100s][%d%%][ %c ]\r", bar, rate, table[rate%4]);fflush(stdout);bar[rate++] = '#';if(rate < 100)bar[rate] = '>';}printf("\n");return 0;
}

        现在进度条实现了查看进度百分比和旋转光标,已经可以和 apt 的进度条媲美了。但是还不够,我们还可以给进度条加上颜色实现彩色的进度条。

C语言输出颜色-CSDN博客

#include <stdio.h>
#include <unistd.h>#define NONE "\033[m"
#define LIGHT_GREEN "\033[1;32m"
#define LIGHT_CYAN "\033[1;36m"
#define LIGHT_PURPLE "\033[1;35m"char bar[101] = ""; //100个#号,一个\0
char* table = "|/-\\";int main()
{int rate = 0;while(rate <= 100){usleep(50000);printf(LIGHT_GREEN"[%-100s]"NONE LIGHT_CYAN"[%d%%]"NONE LIGHT_PURPLE"[ %c ]"NONE"\r", bar, rate, table[rate % 4]);fflush(stdout);bar[rate++] = '#';if(rate < 100)bar[rate] = '>';}printf("\n");return 0;
}

         现在进度条已经写好了,现在我们要对它进行封装。把它的主体封装起来,方便我们后面去调用它。

        创建一个头文件和源文件。因为进度条本身是不知道一件事情的进度目前是多少,进度只有去调用进度条的人才知道,所以进度条的 rate 进度不能封装进去。

ssddffaa@Server-Ubuntu:~/mini-program/ProcessBar$ ls
main.c  Makefile  processbar.c  processbar.h  process-debug.out  process.out

 processbar.h

#pragma once
#include <stdio.h>
#include <string.h>
#include <unistd.h>#define BAR 101
#define BODY '='
#define CUR '>'#define NONE "\033[m"
#define LIGHT_GREEN "\033[1;32m"
#define LIGHT_CYAN "\033[1;36m"
#define LIGHT_PURPLE "\033[1;35m"extern void processbar(int rate);

 processbar.c

#include "processbar.h"char bar[BAR] = "";
const char* table = "|/-\\";void processbar(int rate)
{printf(LIGHT_GREEN"[%-100s]"NONE LIGHT_CYAN"[%d%%]"NONE LIGHT_PURPLE"[ %c ]"NONE"\r", bar, rate, table[rate % 4]);fflush(stdout);bar[rate++] = BODY;if (rate < 100)bar[rate] = CUR;if (rate == 101)memset(bar, '\0', sizeof(bar));
}

main.c

#include "processbar.h"
typedef void (*callbar)(int);void Download(callbar cb)
{int total = 1100;int cnt = 0;while (cnt <= total){usleep(50000);int rate = cnt*100 / total;cb(rate);cnt += 10;}printf("\n");
}int main()
{Download(processbar);return 0;
}

         至此,进度条就写完啦。我们后面想在自己的项目中去使用时就可以通过包含头文件的方式去调用进度条函数。

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

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

相关文章

【typescript/flatbuffer】在websocket中使用flatbuffer

目录 说在前面场景fbs服务器代码前端typescript代码问题 说在前面 操作系统&#xff1a;Windows11node版本&#xff1a;v18.19.0typescript flatbuffer版本&#xff1a;24.3.25 场景 服务器(本文为golanggin)与前端通信时使用flatbuffer进行序列化与反序列化通信协议为websock…

从0开始制作微信小程序

目录 前言 正文 需要事先准备的 需要事先掌握的 什么是uniapp 平台应用的分类方式 什么是TypeScript 创建项目 项目文件作用 源码地址 尾声 &#x1f52d; Hi,I’m Pleasure1234&#x1f331; I’m currently learning Vue.js,SpringBoot,Computer Security and so on.&#x1…

有点混乱的普里姆算法求最小生成树

Graph.h #pragma once //邻接矩阵的创建 #include<stdio.h> #include <stdlib.h> #include<assert.h> #include<string.h> #include<stdbool.h> #include<limits.h> #define MAX 100 #define INF INT_MAX typedef struct Graph {int n;…

一周学会Django5 Python Web开发 - Django5内置Admin系统二次开发

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计56条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

System-Verilog 实现DE2-115倒车雷达模拟

System-Verilog 实现DE2-115倒车雷达模拟 引言&#xff1a; 随着科技的不断进步&#xff0c;汽车安全技术也日益成为人们关注的焦点。在众多汽车安全辅助系统中&#xff0c;倒车雷达以其实用性和高效性脱颖而出&#xff0c;成为现代汽车不可或缺的一部分。倒车雷达系统利用超声…

idea中导入代码文件无法修改,显示File is read-only,怎么办?难办?那就别办了------看下面

File is read-only 文件属性只读&#xff0c;不可修改。。。。。 第一次遇到这种问题&#xff0c;去网上搜了一堆方法&#xff0c;都试了&#xff0c;没用&#xff0c;最后居然还建议我重装idea&#xff0c;我还差点信了&#xff0c;经9X9难后&#xff0c;取得真经。 问题解决…

Spring Boot项目中,如何在yml配置文件中读取maven pom.xml文件中的properties标签下的属性值

一、前言 在最近的项目开发过程中&#xff0c;有一个需求&#xff0c;需要在Spring Boot项目的yml配置文件中读取到mave的 pom.xml文件中的properties标签下的属性值&#xff0c;这个要怎么实现呢&#xff1f; 二、技术实践 pom.xml文件中增加测试属性 <properties><…

汇舟问卷:兼职做国外问卷三小时挣200

在繁忙的都市生活中&#xff0c;许多人为了生计而日夜奔波。对于大多数人来说&#xff0c;白天的工作已经足够充实&#xff0c;但依然有很多人选择在下班时间&#xff0c;多做些什么&#xff0c;为自己带来一份额外​的收入。 目前下班做的兼职工作不是跑滴滴&#xff0c;就是…

YOLOV10:参数越少,速度越快,性能更高的新一代目标检测框架

摘要 在过去的几年中&#xff0c;YOLOs由于在计算成本和检测性能之间实现了有效的平衡&#xff0c;已经成为实时目标检测领域的主导范式。研究人员已经探索了YOLOs的架构设计、优化目标、数据增强策略等&#xff0c;取得了显著的进展。然而&#xff0c;对非极大值抑制&#xf…

Redis学习笔记【基础篇】

SQL vs NOSQL SQL&#xff08;Structured Query Language&#xff09;和NoSQL&#xff08;Not Only SQL&#xff09;是两种不同的数据库处理方式&#xff0c;它们在多个维度上有所差异&#xff0c;主要区别包括&#xff1a; 数据结构: SQL&#xff08;关系型数据库&#xff09;…

深入探讨npm、Yarn、pnpm和npx之间的区别

前端生态系统是一个快速发展的领域&#xff0c;充满了各种工具和技术。对于开发人员来说&#xff0c;跟上这些创新可能是一项艰巨的挑战。 在本文中&#xff0c;我们将深入探讨npm、Yarn、pnpm和npx之间的区别&#xff0c;帮助你理解每个工具的不同之处。 包管理器比较 npm …

【一生一芯】

目录 安装Ubuntu 22.04 安装Ubuntu 22.04 我站在巨人的肩膀上&#xff0c;安装教程见VMware安装Ubuntu22.04(英文桌面)教程 备忘一下&#xff1a; 1.Ubuntu中在终端进入root权限但是总提示密码错误的解决方案 对支持 IPv6 的镜像主机执行 ping 操作&#xff1a; 将帐户添加到 …

私有大模型:针对长结构文档的回答方法

作者: Jon Saad-Falcon, Joe Barrow, Alexa Siu, Ani Nenkova, David Seunghyun Yoon, Ryan A. Rossi, Franck Dernoncourt 摘要: 大型语言模型&#xff08;LLMs&#xff09;在处理长文档问答&#xff08;QA&#xff09;时面临着无法适应其小上下文窗口的问题。为了解决这一问…

【计算机视觉】数字图像处理基础知识(模拟和数字图像、采样量化、像素的基本关系、灰度直方图、图像的分类)

一、图像的基本概念 图像(image)&#xff1a;图像这个简单单词其实包含两方面含义&#xff1a; “图”&#xff1a;是指物体反射光or透射光的分布“像”&#xff1a;接收和记录其分布所得到的结果&#xff08;如&#xff1a;人的视觉系统所接收“图”在人脑中形成的映像或认识&…

LLVM入门教学——SanitizerCoverage插桩(Linux)

1、介绍 LLVM 的 SanitizerCoverage 是一种代码覆盖工具&#xff0c;设计用于支持基于 fuzzing 的测试和其他安全相关工具。SanitizerCoverage 在编译时插桩代码&#xff0c;以在运行时收集覆盖信息&#xff0c;从而帮助识别未覆盖的代码路径&#xff0c;提高测试的有效性和全…

算法-随机快排及荷兰国旗优化

文章目录 算法介绍 :1. 随机快排解析2. 荷兰国旗问题3. 随机快排优化4. 总结随机快排 算法介绍 : 随机快速排序和传统的快速排序的逻辑本质是一致的,都是找到一个值作为划分的中间位置,左边数值均小于该数值,右边数值均大于该数值,但是与传统的快排又不一致的是,我们的这个位置…

国内的期权模拟账户怎么申请?

国内的期权模拟账户可以在券商和期权分仓平台处申请开通&#xff0c;期权相比于股票具有杠杆投资、风险控制等新特性。 期权模拟交易客户端能够提供期权的开平仓交易、备兑开仓&#xff0f;平仓、行权等交易指令&#xff0c;下文为大家介绍国内的期权模拟账户怎么申请&#xff…

2024 cicsn Ezheap

文章目录 检查 libc2.35利用adddeleeditshow 思路exp结果 检查 libc2.35 利用 add 0x80个chunk&#xff0c;遍历选一个没有被用的&#xff0c;输入的size<0x501,然后malloc后会清零安装输入的size&#xff0c;然后输入内容&#xff0c;长度也是输入的size dele 指定索引…

第十六课,海龟画图:设置画笔颜色、宽度函数,移动画笔函数

一&#xff0c;turtle.color()&#xff1a;画笔颜色函数 这个函数能设置画笔画出来的颜色&#xff0c;当然&#xff0c;使用它之前你需要认识有哪些“颜料”可供你选择&#xff0c;turtle库的color()函数可以选择以下颜色&#xff1a; "white" 白色&#xff08;建议…

3步轻松月入过万,APP广告新模式大揭秘!

万万没想到&#xff1a;用这个APP广告模式&#xff0c;月入过万竟然如此简单&#xff01; 在移动应用开发的世界里&#xff0c;变现一直是一道难题。 许多APP开发者和产品经理为了提高收益、增强用户黏性&#xff0c;不断尝试各种策略。 然而&#xff0c;很多时候&#xff0c…