【linux】Linux第一个小程序-进度条

1. 预备知识:回车和换行

回车(Carriage Return,CR):

  • 在早期的机械打字机中,回车指的是将打字机的打印头移回到行首的操作,这样打印头就可以开始新的一行的打印。
  • 在ASCII编码中,回车用控制字符CR表示,其编码为\r(即十进制的13)。

换行(Line Feed,LF):

  • 换行是指将打印头向下移动到下一行的操作。
  • 在ASCII编码中,换行用控制字符LF表示,其编码为\n(即十进制的10)。

即:回车,回到当前行的行首,不会切换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
换行,换到当前位置的下一行,而不会回到行首。

在Windows系统中,文本文件的换行符通常是回车加换行(CR+LF,即\r\n)。而在Unix/Linux系统中,换行符仅仅是LF(\n)(Unix/Linux下这个\n就就包括了回车和换行)。

2. 预备知识:缓冲区

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

在这里插入图片描述

在linux下编译运行以上代码,发现在前三秒"hello world!"并未被打印到屏幕上,三秒之后被打印到屏幕上。那么此前三秒,它被储存到了那里呢?
答案是缓冲区,缓冲区(Buffer)主要应用于提高系统性能和效率。缓冲区通常指的是内存中的一段连续区域,用于临时存储数据,减少CPU、内存和外部设备(如硬盘、网络等)之间的交互次数。当应用程序向文件或设备进行读写操作时,数据会首先被存储到缓冲区中,然后再由缓冲区根据特定的刷新策略将数据写入磁盘或设备中。

缓冲区被刷新到显示器上的几种方式:

  • 程序结束的时候,一般要自动冲刷缓冲区
  • \n
  • 缓冲区满了,自动刷新
  • fflush() 函数强制刷新

3. 进度条

此文件夹下新建一个makefile文件:

processbar: Main.c Processbar.cgcc -o $@ $^         //选项 -o $@ 指定输出文件名,其中 $@ 是一个自动变量,代表当前规则的目标(在这里即为processbar)。而 $^ 是另一个自动变量,表示所有依赖文件的集合(即Main.c和Processbar.c).PHONY: clean
clean:rm -f processbar

这是一个用于将Main.cProcessbar.c源文件编译并链接成名为processbar的可执行文件的简单Makefile

这个Makefile提供了两种操作:
1.运行make processbar以编译并链接Main.cProcessbar.c源文件,生成processbar可执行文件。
2.运行make clean以删除processbar可执行文件,清理项目构建产物。

进度条代码版本一:(仅仅是进度条的模拟)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果void ProcBar();////version 1
void ProcBar()
{char bar[Length];   //进度条的显示长度memset(bar,'\0',sizeof(bar));  //先初始化为'\0'填充清零int len=strlen(lable);int cnt=0;while(cnt<=100)    //使用循环结构,从0迭代到100,每次迭代表示进度的1%{printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%len]);   //用回车并不是换行,每次打印进度条都从当前行头部开始打印fflush(stdout);    //强制刷新标准输出缓冲区,确保进度条立刻显示在屏幕上bar[cnt++]=Style;   //进度条数组bar的相应位置添加进度样式字符usleep(200000);    //用于休眠一段时间,模拟任务执行过程。(休眠单位为微秒)}printf("\n");
}int main()
{ProcBar();return 0;
}

这段C语言代码实现了一个简单的进度条功能,用于模拟某个长时间运行的任务(如文件下载、处理任务等)的进度展示。

效果演示:
在这里插入图片描述

进度条代码版本二:(模拟一个下载任务,根据下载任务的进度打印进度条)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果void ProcBar();////version 2
////配合场景使用
//进度条每执行一次循环就刷新一次,会出现闪烁(我还挺喜欢这个的)
void ProcBar(double total, double current)    //total代表总任务量(即文件大小),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;       //计算进度百分比rate和对应的循环次数loop_countwhile (cnt <= loop_count){printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);fflush(stdout);bar[cnt++] = Style;//usleep(200000);  //这个也不需要了,在另一个调它的函数download()中有}//printf("\n");
}//模拟下载单个文件
void download()
{double filesize = 100 * 1024 * 1024 * 1.0; // 文件大小100兆double current = 0.0; // 当前下载量double bandwidth = 1024 * 1024 * 1.0; // 网络带宽1兆printf("download begin, current: %lf\n", current);while (current <= filesize)   //使用一个循环来模拟下载过程,每次迭代都更新current的值,并调用ProcBar函数来更新和显示进度条。{// 打印进度条ProcBar(filesize, current);// 从网络获取数据current += bandwidth;usleep(10000);    //模拟网络下载的速度}printf("\ndownload complete!   filesize:%lf\n", filesize);
}int main()
{// 下载测试(模拟单个文件下载)// download();return 0;
}

这段代码实现了一个简单的进度条功能(ProcBar())和一个模拟单个文件下载的函数(download())。实际使用时,只需将download()中的相关参数替换为实际的下载信息,并调用此函数即可在控制台显示下载进度。

效果演示:
在这里插入图片描述

进度条代码版本三:(模拟多个下载任务,根据下载任务的进度打印进度条)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果typedef void(*callback_t)(double,double);  //函数指针  
void ProcBar();//闪烁版
//void ProcBar(double total, double current)    //total代表总任务量(即文件大小),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;       //计算进度百分比rate和对应的循环次数loop_count
//
//    while (cnt <= loop_count)
//    {
//        printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);
//        fflush(stdout);
//        bar[cnt++] = Style;
//        //usleep(200000);  //这个也不需要了,在另一个调它的函数download()中有
//    }
//
//    //printf("\n");
//}// version 3
// 配合场景使用
// 每次调用函数时直接将bar拼接起来,循环执行完后再刷新,这样就不会出现闪烁
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;       //计算进度百分比rate和对应的循环次数loop_countwhile (cnt <= loop_count){bar[cnt++] = Style;}// 填充完成后,一次性打印出完整的进度条,并刷新输出,避免了闪烁现象printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);fflush(stdout);  
}
//此版本进度条与之前版本不同的是,它在循环中先将进度条字符逐个拼接到bar数组中,待循环完成后一次性刷新输出,从而避免了进度条的闪烁现象。// 模拟下载多个文件
double bandwidth = 1024 * 1024 * 1.0;  // 网络带宽1兆
void download(double filesize, callback_t cb)   // 此处用函数指针也很方便
{double current = 0.0; // 当前下载量printf("download begin, current: %lf\n", current);while (current <= filesize)   //使用一个循环来模拟下载过程,每次迭代都更新当前下载量current,并调用回调函数cb来更新和显示进度条{cb(filesize, current);// 从网络获取数据current += bandwidth;usleep(10000);  //模拟下载速度时,每次迭代都增加bandwidth(网络带宽)的值到current,并使用usleep函数来模拟网络延迟}printf("\ndownload complete!   filesize:%lf\n", filesize);
}int main()
{// 多个文件下载测试download(200 * 1024 * 1024, ProcBar);download(400 * 1024 * 1024, ProcBar);download(50 * 1024 * 1024, ProcBar);download(10 * 1024 * 1024, ProcBar);return 0;
}

这段C代码通过定义一个进度条更新函数ProcBar和一个模拟下载函数download,实现了在控制台中展示动态进度条的功能,并模拟了多个文件的下载过程。通过回调函数的使用,使得download函数可以灵活地与不同的进度条更新函数配合使用。

效果演示:
在这里插入图片描述

闪烁版演示效果:
在这里插入图片描述

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

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

相关文章

AIGC-stable-diffusion(文本生成图片)+PaddleHub/HuggingFace

功能 stable-diffusion(文本生成图片)PaddleHub&#xff0c;HuggingFace两种调用方式 PaddleHub 环境 pip install paddlepaddle-gpu pip install paddlehub 代码 from PIL import Image import paddlehub as hub module hub.Module(namestable_diffusion)## 保存在demo…

NXP恩智浦 S32G电源管理芯片 VR5510 安全概念 Safety Concept (万字长文详解,配21张彩图)

NXP恩智浦 S32G电源管理芯片 VR5510 安全概念 Safety Concept (万字长文详解&#xff0c;配21张彩图) 1. 简介 本应用笔记描述了与S32G处理器和VR5510 PMIC相关的安全概念。该文档涵盖了S32G和VR5510的安全功能以及它们如何相互作用&#xff0c;以确保对ASIL D安全完整性级别…

STM32,复位和时钟控制

外部时钟 HSE 以后需要用到什么就这样直接拿去配就行了

【文件上传与包含漏洞综合利用】DVWA-文件上传-难度:High

实验过程和结果 步骤1&#xff1a;尝试直接上传php木马&#xff0c;失败&#xff0c;截图如下&#xff1a; 步骤2&#xff1a;将php木马后缀改为jpeg尝试上传&#xff0c;依旧失败&#xff0c;截图如下&#xff1a; 步骤3&#xff1a;将真实的jpeg图片1.jpeg上传&#xff0c;成…

企业微信hook接口协议,ipad协议http,外部联系人图片视频文件下载

外部联系人文件下载 参数名必选类型说明file_id是StringCDNkeyopenim_cdn_authkey是String认证keyaes_key是Stringaes_keysize是int文件大小 请求示例 {"url": "https://imunion.weixin.qq.com/cgi-bin/mmae-bin/tpdownloadmedia?paramv1_e80c6c6c0cxxxx3544d9…

智慧火电厂合集 | 数字孪生助推能源革命

火电厂在发电领域中扮演着举足轻重的角色。主要通过燃烧如煤、石油或天然气等化石燃料来产生电力。尽管随着可再生能源技术的进步导致其比重有所减少&#xff0c;但直至 2023 年&#xff0c;火电依然是全球主要的电力来源之一。 通过图扑软件自主研发 HT for Web 产品&#xf…

[Algorithm][前缀和][和为K的子数组][和可被K整除的子数组][连续数组][矩阵区域和]详细讲解

目录 1.和为 K 的子数组1.题目链接2.算法原理详解3.代码实现 2.和可被 K 整除的子数组1.题目链接2.算法原理详解3.代码实现 3.连续数组1.题目链接2.算法原理详解3.代码实现 4.矩阵区域和1.题目链接2.算法原理详解3.代码实现 1.和为 K 的子数组 1.题目链接 和为 K 的子数组 2.…

牛客 题解

文章目录 day4_17**BC149** **简写单词**思路&#xff1a;模拟代码&#xff1a; dd爱框框思路&#xff1a;滑动窗口&#xff08;同向双指针&#xff09;代码&#xff1a; 除2&#xff01;思路&#xff1a;模拟贪心堆代码&#xff1a; day4_17 BC149 简写单词 https://www.now…

如何在 Ubuntu 14.04 上配置 StatsD 以收集 Graphite 的任意统计数据

介绍 Graphite 是一个图形库&#xff0c;允许您以灵活和强大的方式可视化不同类型的数据。它通过其他统计收集应用程序发送给它的数据进行图形化。 在之前的指南中&#xff0c;我们讨论了如何安装和配置 Graphite 本身&#xff0c;以及如何安装和配置 collectd 以编译系统和服…

【MATLAB源码-第197期】基于matlab的粒子群算法(PSO)结合人工蜂群算法(ABC)无人机联合卡车配送仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 基于粒子群优化&#xff08;PSO&#xff09;算法的无人机联合卡车配送系统是一个高效的物流配送策略&#xff0c;旨在优化配送过程中的成本、时间和资源利用率。该系统融合了无人机和卡车的配送能力&#xff0c;通过智能算法…

Tiny11作者开源:利用微软官方镜像制作独属于你的Tiny11镜像

微软对Windows 11的最低硬件要求包括至少4GB的内存、双核处理器和64GB的SSD存储。然而&#xff0c;这些基本要求仅仅能保证用户启动和运行系统&#xff0c;而非流畅使用 为了提升体验&#xff0c;不少用户选择通过精简系统来减轻硬件负担&#xff0c;我们熟知的Tiny11便是其中…

【简单介绍下机器学习之sklearn基础】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

【机器学习】深度神经网络(DNN):原理、应用与代码实践

深度神经网络&#xff08;DNN&#xff09;&#xff1a;原理、应用与代码实践 一、深度神经网络&#xff08;DNN&#xff09;的基本原理二、DNN的优缺点分析三、DNN的代码实践四、总结与展望 在人工智能与机器学习的浪潮中&#xff0c;深度神经网络&#xff08;Deep Neural Netw…

演示在一台Windows主机上运行两个Mysql服务器(端口号3306 和 3307),安装步骤详解

目录 在一台Windows主机上运行两个Mysql服务器&#xff0c;安装步骤详解因为演示需要两个 MySQL 服务器终端&#xff0c;我只有一个 3306 端口号的 MySQL 服务器&#xff0c;所以需要再创建一个 3307 的。创建一个3307端口号的MySQL服务器1、复制 mysql 的安装目录2、修改my.in…

安全开发实战(4)--whois与子域名爆破

目录 安全开发专栏 前言 whois查询 子域名 子域名爆破 1.4 whois查询 方式1: 方式2: 1.5 子域名查询 方式1:子域名爆破 1.5.1 One 1.5.2 Two 方式2:其他方式 总结 安全开发专栏 安全开发实战​​http://t.csdnimg.cn/25N7H 前言 whois查询 Whois 查询是一种用…

MCU功耗测量

功耗测量 一、相关概念二、功耗的需求三、测量仪器仪表测量连接SMU功能SMU性能指标 四、功耗测量注意点板子部分存在功耗MCU方面&#xff0c;可能存在干扰项仪器仪表方面 一、相关概念 静态功耗和动态功耗&#xff1a;动态功耗为运行功耗&#xff0c;功耗测量注重每MHz下的功耗…

DevOps文化对团队有何影响?

DevOps文化对团队有很多积极影响&#xff0c;包括提高团队效率、促进沟通与协作、提高产品质量和推动创新等方面。然而&#xff0c;实施DevOps文化也需要一定的挑战&#xff0c;如改变团队成员的观念、引入新的工具和流程等。因此&#xff0c;团队需要充分了解DevOps文化的价值…

【重磅开源】MapleBoot项目开发规范

基于SpringBootVue3开发的轻量级快速开发脚手架 &#x1f341;项目简介 一个通用的前、后端项目模板 一个快速开发管理系统的项目 一个可以生成SpringBootVue代码的项目 一个持续迭代的开源项目 一个程序员的心血合集 度过严寒&#xff0c;终有春日&#xff…

计算机网络-IS-IS基础配置实验

前面我们了解了IS-IS的一些基础理论&#xff0c;从建立邻接、链路状态数据库同步以及路由计算&#xff0c;现在开始学习下配置操作。 一、IS-IS配置 网络拓扑图&#xff1a; 拓扑图 IS-IS有Level级别的区分&#xff0c;Level-1可以是性能较低的设备只维护区域内的LSDB&#xff…

《R语言与农业数据统计分析及建模》学习——描述性统计分析

一、描述性统计概念和方法 1、概念和作用 描述性统计是对数据进行概括和描述&#xff0c;便于理解数据的特征、趋势和分布&#xff0c;帮助我们了解数据基本情况和总体特征&#xff0c;为后续更深入的数据分析和建模提供基础。 2、基础方法 &#xff08;1&#xff09;中心趋…