进度条程序的编写

news2024/11/25 8:17:45

目录

  回车换行和换行的区别

  倒计时程序

  进度条程序

  进度条代码的优化 version2

   进度条代码的优化version3

  在编写进度条程序之前我们需要先了解一个概念:回车换行和换行的区别。

  回车换行和换行的区别

  刚听到的时候会很好奇,回车换行和换行有什么区别吗?我们之前都使用过 ‘ \n ’ 作为换行符让我们的输出结果更换所在行。但是他发挥的作用只是回车换行的作用吗?

  在我们所熟知的 \n 的作用下我们会发现输出结果确实到达了下一行。但是我们很容易忽略一件事:我们的光标的位置也到了下一行的行首。这就是回车换行的关键。

  换行的含义顾名思义就是更换我们的输出行,回车的含义代表了需要让我们的光标回到本行的行首。不知道大家还记不记得我们之前学过的 \r 他的作用其实就是回车。作用就是让我们的光标的位置回到我们本行的行首。之后在进行输出,会忽略后面的字符,输出的时候会进行覆盖操作。简单观察一下现象:

输出结果:

  我们在运行上述代码的时候会发现一个很奇怪的现象:我们代码当中打印的明明是两个hello world呀!为什么只出现一个呢?其实第二个hello world也被打印出来了,只不过被我们的命令行提示符遮盖掉了。

  倒计时程序

  我们可以根据上述原理编写一个简单的倒计时程序,在我们的预期当中我们打印的数字在同一个位置逐渐减小,最终变成零。(实际上就是每次打印一个数字,之后再通过回车回到本行的行首部位,再进行打印输出。)

  

  为了方便我们观察,我们还可以调用sleep函数,让我们输出的结果停留一定的时间之后再继续变化。可是等我们运行的结果却和我们想象当中的并不一样。

  我们得到的效果是程序经过了十秒之后才打印出0,其他步骤都被忽略了。

  这个现象涉及到了缓冲区,为了减缓系统的占有时间,当我们的输出数据较少的时候就会暂时放到缓冲区当中不进行输出,等到数据足够的时候或者程序结束的时候才进行输出。所以我们的所有数据都放到缓冲区当中,同时数据又被 \r 覆盖,最后就有了这个效果。要想让我们的程序输出想要的结果。我们就需要调用fflush函数,fflush函数会主动刷新缓冲区,输出我们的结果。将我们的代码修改成为如下示例即可:

   修改完成之后使用gcc进行编译,我们可以发现程序一切都正常进行。

  进度条程序

  当我们的倒计时程序编写完毕之后,我们就可以来编写我们的进度条程序了。

  在我们的想象中,进度条需要随着时间的推荐逐渐向前推进,后面还需要有显示已经下载的进度,最后是正在下载的标志。也类似于我们日常生活当中见到的转圈圈的标志。

  我们想象当中的进度条的样子就是上面的。如果感兴趣的话我们之后还可以使用图形化界面进行封装,最后就可以得到我们平常见到的进度条了,但是今天我们先来学习底层逻辑。

  首先我们来完成进度条的主体。像我们看到的一样,我们进度条的主体是一堆用 = 以及 > 组成的字符,所以我们就可以使用一个字符串数组进行表示,其中因为加载进度为 0-100 所以我们需要100个有效的字符,加上我们表示字符串结束的标志一共需要101个有效的字符空间。每次我们只需要对我们的字符数组进行修改并输出即可。

  

  在程序编写之前我们可以创建好,向上面的三个文件。在 test.c 文件当中我们只需要调用函数即可。我们的程序想要成功的输出我们也只需要在 progress.c 文件当中实现progress函数即可。

  就像是上图中最右边的文件当中所示的那样:我们每次打印数组当中的内容,之后将目标字符输入到字符数组当中,最后刷新缓冲区,并休眠一段时间即可。代码产生的效果如下:

  类似于我们正常进度条一样,一点一点向右边进行推进。

  但是只有一个进度条的主体是完全不够的,我们还需要进行调整。加上我们打印的进度条的进度,以及正在打印的标志。我们只需要修改打印输出的那一行内容即可:

  代码修改为:

  需要注意的是我们在输出 % 的时候需要使用转义字符进行输出,否则可能会产生意想不到的输出效果。

  进度条代码的优化 version2

  我们会发现这和我们平时的进度条程序看起来确实很像,但是如何使用呢?

  事实上想要使用我们编写好的进度条程序的话我们还需要对我们的代码进行简单的进行修改以及优化,我们需要设置一个参数用于接收下载的进度,进而打印出指定的进度条,这样才可以反映出我们具体的下载的情况,所以我们需要将代码修改成为:  

  我们将参数修改成比例,可以作为我们进度条打印的标志。我们的progress程序只需要将我们这个这个比例下的进度条输出即可,至于其他的操作细节只需要交给我们的用户完成即可。也就是我们右边的 test.c 当中的代码。这样可以增加我们进度条的灵活程度,条件变量我们还可以写成一个新的函数,例如:cur+=change() 我们可以创建一个函数检测一段时间内下载的文件大小,之后就可以实时返回我们的下载进度了。测试效果如下:

  和我们想要的效果也完全相同。

   进度条代码的优化version3

  但是我们又会发现,让用户做这么多事情会不会岂不是违背了我们函数封装的原理?要是有多个下载的内容又该怎么办呢?

  为了解决上面出现过的问题,就有了我们第三版的进度条代码。我们可以将 test.c 当中的内容封装起来,采用我们的回调函数,将progress打印进度条的函数作为参数传给我们的dowload函数。用户只需要在main函数当中嗲用download函数即可。这样不仅减少了用户的代码操作,增加了函数的封装性,还允许我们进行多次的下载操作。修改代码如下:

  首先我们使用typedef将我们的函数指针重命名,便于我们函数的传参,之后我们将之前 test.c 当中的代码全部封装起来,简单的进行修改就成为了我们的 download 函数,之后载 test.c 文件当中只需要调用我们指定的函数即可。代码运行的效果如下:

  但是我们会发现我们的代码仍然有bug,我们在打印的时候只有第一个进度条当中的内容是变化的,其余的程序都是直接显示全满的内容,之后后面的数字和变化符号在变化。

  这是因为我们在第一次打印下载操作执行完成的时候会将我们数组当中的所有的内容从 ‘ \0 ’ 修改成为 = 因此再继续打印的时候会显示字符数组当中的所有的字符。我们可以在每一次下载完毕之后,将我们的数组当中的内容置为 ‘ \0 ’ 以修改这个bug。

    我们只需要在download代码的最后一行加上memset函数,将字符数组重置为0即可。测试效果如下:

  我们发现我们的输出变得符合我们的预期。那么我们的进度条程序也就全部书写完毕了。

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

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

相关文章

【数据结构】树、二叉树的概念和二叉树的顺序结构及实现

目录 前言:一、树的概念及结构1.树的概念2.树的相关概念3.树的存储4.树在实际中的运用 二、二叉树概念及结构1.概念2.特殊的二叉树(1)满二叉树(2)完全二叉树 3.二叉树的性质4.二叉树的存储(1)顺序存储(2)链式存储 三、…

山西电力市场日前价格预测【2023-09-30】

日前价格预测 预测说明: 如上图所示,预测明日(2023-09-30)山西电力市场全天平均日前电价为267.99元/MWh。其中,最高日前电价为485.05元/MWh,预计出现在18: 45。最低日前电价为0.00元/MWh,预计出…

手机搜狗输入法,输入拼音时如何分割拼音,调出“分词“功能,如何微信或QQ使用发送按钮而不是换行?

背景 有时候打字,输入 “xian” 的时候我们的意图是 “xi’an” (西安),或者输入 “yue” 的时候希望是 “yu’e”(余额) 如何输入这个分隔符 ’ 呢? 设置方法 默认页面如图 希望设置成 点…

python安装第三方模块方法

正常情况下安装python第三方模块没啥说的,但是由于python安装模块默认是在外网下载安装,牵扯外网网速问题,所以可以配置下使用国内某镜像源来下载模块 python -m pip install xxxxxxxxxxx 和 pip install xxxxxxxxxx 的命令都可下载安装第三…

Junit单元测试为什么不能有返回值?

这个问题的产生来源于我们老师上节课说的我们班一个男生问他的想法,刚开始听到这个还觉得挺有意思,我之前使用单元测试好像下意识的就将它的返回值写为void,一般都是进行简单的测试,也从没思考过在某个单元测试中调用另一个单元测试&#xff…

2023年【起重信号司索工(建筑特殊工种)】考试总结及起重信号司索工(建筑特殊工种)模拟考试题

题库来源:安全生产模拟考试一点通公众号小程序 起重信号司索工(建筑特殊工种)考试总结是安全生产模拟考试一点通生成的,起重信号司索工(建筑特殊工种)证模拟考试题库是根据起重信号司索工(建筑特殊工种)最新版教材汇编出起重信号司索工(建筑特殊工种)仿…

Muduo网络库之Channel、EPollPoller与EventLoop类【深度解析】

文章目录 前言一、Channel类1、主要成员变量以及函数2、实现原理 二、EPollPoller类1、实现原理 二、EventLoop类1、功能实现SubReactorde的唤醒操作 前言 重新梳理一遍muduo网络库的类与知识点。 Channel、EPollPoller与EventLoop类是muduo库最重要的基础, 他们三…

python-切换镜像源和使用PyCharm进行第三方开源包安装

文章目录 前言python-切换镜像源和使用PyCharm进行第三方开源包安装1. 切换镜像源2. 使用PyCharm进行第三方开源包安装 前言 如果您觉得有用的话,记得给博主点个赞,评论,收藏一键三连啊,写作不易啊^ _ ^。   而且听说点赞的人每…

【Java 进阶篇】MySQL多表查询:内连接详解

MySQL是一种强大的关系型数据库管理系统,允许您在多个表之间执行复杂的查询操作。本文将重点介绍MySQL中的多表查询中的一种重要类型:内连接(INNER JOIN)。内连接用于检索满足两个或多个表之间关联条件的行,它能够帮助…

【Leetcode】 501. 二叉搜索树中的众数

给你一个含重复值的二叉搜索树(BST)的根节点 root ,找出并返回 BST 中的所有 众数(即,出现频率最高的元素)。 如果树中有不止一个众数,可以按 任意顺序 返回。 假定 BST 满足如下定义&#xf…

严重影响Windows使用体验的一些建议

1内存不够用:通过观察我发现我的电脑已经评价到了90%的内存使用率 没有内存什么程序运行起来都会卡的,所以一定要把不用的PROGRAME给他删除掉。特别是那些自动启动的软件,如果实在不行,就把杀毒也给他卸载掉。 不良具体表现&…

人物重识别(ReID):AaP-ReID: Improved Attention-Aware Person Re-identification

论文作者:Vipin Gautam,Shitala Prasad,Sharad Sinha 作者单位:Indian Institute of Technology Goa 论文链接:http://arxiv.org/abs/2309.15780v1 内容简介: 1)方向:人物重识别(ReID&#…

Acer宏碁笔记本暗影骑士轻刃AN715-51原装出厂Windows10系统工厂模式镜像

系统自带所有驱动、NITROSENSE风扇键盘灯控制中心、Office办公软件、出厂主题壁纸、系统属性Acer宏基专属的LOGO标志、 Acer Care Center、Quick Access等预装程序 下载链接:https://pan.baidu.com/s/1FDCP5EONlk0o12CYFXbhrg?pwdvazt 所需要工具:32G…

word 多级目录的问题

一、多级标题自动编号 --> 制表符 -> 空格 网址: 【Word技巧】2 标题自动编号——将多级列表链接到样式 - YouTube 二、多级列表 --> 正规形式编号 网址:Word 教学 - 定框架:文档格式与多级标题! - YouTube 三、目…

2023年【安徽省安全员C证】模拟考试题及安徽省安全员C证实操考试视频

题库来源:安全生产模拟考试一点通公众号小程序 2023年【安徽省安全员C证】模拟考试题及安徽省安全员C证实操考试视频,包含安徽省安全员C证模拟考试题答案和解析及安徽省安全员C证实操考试视频练习。安全生产模拟考试一点通结合国家安徽省安全员C证考试最…

力扣:113. 路径总和 II(Python3)

题目: 给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 来源:力扣(LeetCode) 链接:力扣(…

Netty(三)NIO-进阶

Netty进阶 1. 粘包与半包 1.1 粘包现象 //client端分10次每次发送16字节数据 public void channelActive(ChannelHandlerContext ctx) {for (int i 0; i < 10; i) {ByteBuf buf ctx.alloc().buffer(16);buf.writeBytes(new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, …

【嵌入式 – GD32开发实战指南(ARM版本)】第2部分 外设篇 - 第1章 温湿度传感器DHT11

1 理论分析 1.1 DHT11介绍 DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。 DHT11传感器包括一个电阻式感湿元件和一个 NTC 测温元件,并与一个高性能…

2、MQ高级

在昨天的练习作业中&#xff0c;我们改造了余额支付功能&#xff0c;在支付成功后利用RabbitMQ通知交易服务&#xff0c;更新业务订单状态为已支付。 但是大家思考一下&#xff0c;如果这里MQ通知失败&#xff0c;支付服务中支付流水显示支付成功&#xff0c;而交易服务中的订单…

C++核心编程--继承篇

4.6、继承 继承是面向对象三大特征之一 有些类与类之间存在特殊的关系&#xff0c;例如下图中&#xff1a; ​ 我们发现&#xff0c;定义这些类的定义时&#xff0c;都拥有上一级的一些共性&#xff0c;还有一些自己的特性。那么我们遇到重复的东西时&#xff0c;就可以考虑使…