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

这篇博客要综合利用以前的知识,来实现一个进度条程序~

目录

换行&回车

缓冲区

实现简单的倒计时

实现进度条

version1

version2


 

在开始写这个小程序之前,我们先学习一些预备知识:

换行&回车

缓冲区

 在我们运行这个程序时,并没有直接打印出“hello bit,hello world...”,而是当程序运行结束后才显示出来,但是这并不代表这句打印没有执行,而是没有显示出来而已。

那么,在我sleep期间,字符串在哪里?

答案就是被保存在叫做缓冲区的地方,就是一块内存空间,当程序结束时,一般会自动刷新缓冲区到字符设备(显示器),另外,如果程序遇到‘\n’的时候,也会刷新缓冲区。如果想要强制刷新,可以使用fflush命令。

那么,为什么要有缓冲区呢,为什么按行刷新?为了提高效率,方便人类阅读,人类读信息都是按行读的,是一种尊重用户的表现

 实现简单的倒计时

在实现倒计时中,我们想要达到的效果是依次显示数字,并且下一个覆盖前一个数字,创建test.c文件:

  1 #include <stdio.h>2 #include <unistd.h>3 4 int main()5 {6   int cnt=10;7   while(cnt >=0)8   {9     printf("倒计时:%2d\r",cnt);                                                                                                              10     fflush(stdout);11     cnt--;12     sleep(1);13   }14   printf("\n");15 16   return 0 ;17 }

我们实现的效果是10,9,...1,0的倒计时效果,其中,

printf("倒计时:%2d\r",cnt);

这句代码中\r是回车,在一次打印完成后,光标回到最前面,继续打印下一个值,覆盖掉上一次的值,用%2d的格式打印的原因是,每次打印两个字符,以防某个字符一直在屏幕上显示。使用fflush(stdout)强制刷新到显示器上。

此外,我们还写了makefile自动化构建工具:

 mycode:test.c2   gcc -o $@ $^3 .PHONY:clean4 clean:5   rm -f mycode

至此完成了简单的倒计时效果。

实现进度条

version1

在实现进度条中,我们要创建三个文件:Processbar.h,Processbar.c,Main.c,Main.c负责将Processbar.h中的方法进行调用,最终想达到的效果如下图:

在Processbar.h中,我们定义了Process函数声明;

#pragma once                                                                                                                                 
#include <stdio.h>
extern void Process();

在Processbar.c中实现了Process:

 #include "Processbar.h"#include <string.h>#include <unistd.h>#define Length 101#define Style '#'const char * label = "|/-\\";// version1void Process(){char bar[Length];memset(bar,'\0',sizeof(bar));int cnt = 0;int len =strlen(label);while(cnt <= 100){printf("[%-100s][%3d%%][%c]\r",bar,cnt,label[cnt%len]);fflush(stdout);   bar[cnt++]=Style;usleep(20000);}printf("\n");}

在上面这段程序中,我们用bar数组来实现进度条,大小Length设为101(包括最后的‘\0’),进度条符号为‘#’。[%-100s]表示字符串靠左对齐,保证了‘#’从左边往右增长。通过循环遍历label所指向的数组来实现旋转光标的效果。

需要注意的是,因为每次使用‘\r’来实现覆盖的效果,但是‘\r’不能让每次结果刷新到显示器上,需要用fflush(stdout)来刷新。usleep()函数的单位是微秒(包含unistd.h头文件)。

在Main.c中,调用Process.h:

#include "Processbar.h"                                                                                                                                                                      
int main()                                                                                  {                                                                                                                                                 Process();                                                                                                                                 return 0;                                                                                               
}    

最终的实现效果:

version2

上面我们单独写了一个进度条程序,但是,进度条会单独出现吗?肯定不会!它要和具体的场景结合。

假设我们要完成一个下载的场景:下载指定大小的文件,

在Main.c中,我们写出download()这样一个函数:

   double bandwidth = 1024*1024*1.0;                                                                                                                        //downloadvoid download(double filesize,callback_t cb){//double filesize = 100*1024*1024*1.0;double current = 0.0;printf("download begin,current:%lf\n",current);while(current <= filesize){cb(filesize,current);//从网络中获取current += bandwidth;usleep(10000);}printf("\ndownload done,filesize:%lf\n",filesize);}

其中,bandwidth是我们假设的带宽(可以理解为下载速度),download函数的filesize参数是我们要下载的文件大小,第二个参数是进度条打印函数,callback_t是函数指针,其定义在Processbar.h中,

typedef void(*callback_t)(double,double); 

在while循环中,根据filesize和current的大小,打印出当前下载进度的进度条,打印完成后,继续下载,current继续增加,然后再打印下一次的进度条并覆盖之前的进度条。

在Processbar.h中,有如下声明:

#pragma once 
#include <stdio.h> 
typedef void(*callback_t)(double,double);                                                                                                                
void Process(double total,double current);

在Processbar.c中,定义了Process函数:

//version2
void Process(double total,double current)
{char bar[Length];memset(bar,'\0',sizeof(bar));int cnt = 0;int len =strlen(label);double rate = current*100.0/total;int loop_count = (int)rate;                                                                                                                            while(cnt <= loop_count){bar[cnt++]=Style;}printf("[%-100s][%.1lf%%][%c]\r",bar,rate,label[cnt%len]);fflush(stdout);   }

根据总文件大小total和当前已下载大小current,打印出当前的进度条,例如,当total=100、current=36时,会打印出如下内容:

在Main.c中,将Process函数作为实参传给download()函数,完成下载。

int main()
{download(100*1024*1024,Process);download(50*1024*1024,Process);                                                                                                                        download(80*1024*1024,Process);download(1*1024*1024,Process);download(18*1024*1024,Process);return 0;
}

 模拟下载了多个文件,其效果如下:

 

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

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

相关文章

git workflow

分支策略 按分支属性分类 主干分支&#xff1a;master特性分支&#xff1a;feature-[序号]、fix-[序号]、hotfix-[序号]开发分支&#xff1a;dev-[序号]-[开发者]发布分支&#xff1a;release-[版本号]部署分支&#xff1a;release&#xff08;正式&#xff09;、test&#xf…

如何阅读“计算机界三大神书”之一 ——《计算机程序的构造和解释》SICP

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

如何使用 @font-face 和 font-display 在 CSS 中定义自定义字体

介绍 font-face 是一个 CSS at-rule&#xff0c;用于定义自定义字体。通过 font-face&#xff0c;您可以提供一个路径到与您的 CSS 文件托管在同一服务器上的字体文件。这个规则已经存在了相当长的时间&#xff0c;但是有一个更新的属性 font-display&#xff0c;它带来了新的…

STM32CubeMX学习笔记17--- FSMC

1.1 TFTLCD简介 TFT-LCD&#xff08;thin film transistor-liquid crystal display&#xff09;即薄膜晶体管液晶显示器。液晶显示屏的每一个像素上都设置有一个薄膜晶体管&#xff08;TFT&#xff09;&#xff0c;每个像素都可以通过点脉冲直接控制&#xff0c;因而每个节点都…

论文阅读:Scalable Diffusion Models with Transformers

Scalable Diffusion Models with Transformers 论文链接 介绍 传统的扩散模型基于一个U-Net骨架&#xff0c;这篇文章提出了一种新的扩散模型结构&#xff0c;将U-Net替换为一个transformer&#xff0c;并将这种结构称为Diffusion Transformers (DiTs)。他们还发现&#xff…

python77-Python的函数参数,个数可变参数

很多编程语言都允许定义个数可变的参数,这样可以在调用函数时传入任意多个参数。Python当然也不例外,Python 允许在形参前面添加一个星号(*),这样就意味着该参数可接收多个参数值,多个参数值被当成元组传入。下面程序定义了一个形参个数可变的函数。 # !/usr/bin/env pyth…

数据分析 - 面经 - 联蔚数科

2024.1.9 面试 Boss直聘沟通 先简单做下自我介绍吧 你项目中设计的技术选型&#xff0c;你都有使用过是吗&#xff1f; 这个项目的团队规模介绍一下 在数据部分&#xff0c;详细讲一下主要工作&#xff0c;在数据采集&#xff0c;处理等方面 这些工具是学校教的呢&#x…

阿里云服务器使用教程_2024建站教程_10分钟网站搭建流程

使用阿里云服务器快速搭建网站教程&#xff0c;先为云服务器安装宝塔面板&#xff0c;然后在宝塔面板上新建站点&#xff0c;阿里云服务器网aliyunfuwuqi.com以搭建WordPress网站博客为例&#xff0c;来详细说下从阿里云服务器CPU内存配置选择、Web环境、域名解析到网站上线全流…

requests模块的其他方法

requests模块的其他方法 学习目标 掌握requests中cookirJar的处理方法掌握requests解决https证书错误的问题掌握requests中超时参数的使用掌握retrying模块的使用 1 requests中cookirJar的处理方法 使用request获取的resposne对象&#xff0c;具有cookies属性&#xff0c;能够…

Vscode连接远程服务器失败解决方案

一、 could not establish connection to “XXX” 尝试使用Remote-SSH插件连接远程的服务器&#xff0c;但是配置显示出错&#xff0c;端口显示试图写入的管道不存在&#xff0c;弹出窗口显示could not establish connection to “XXX” 二、检查Windows的OpenSSH 1.检索是否…

Java中注解@RequestParam 和 @ApiParam详解

一、RequestParam 和 ApiParam的常用属性 RequestParam 和 ApiParam 是在 Spring MVC 控制器方法中使用的注解&#xff0c;它们分别服务于不同的目的&#xff1a; RequestParam RequestParam 是 Spring MVC 中用来处理 HTTP 请求参数的注解&#xff0c;主要用于绑定请求中的查…

数据分析项目[开发中]

学习进度记录&#xff1a; 12.7&#xff1a; 教程链接&#xff1a;智能 BI 项目教程(一) (yuque.com) 前端&#xff1a; Ant Design Pro&#xff1a;开始使用 - Ant Design Pro​​​​​​ 然后安装依赖 yarn install 去除不需要的&#xff1a; 移除国际化 【报错】 …

【数据结构与算法】二分查找题解(二)

这里写目录标题 一、81. 搜索旋转排序数组 II二、167. 两数之和 II - 输入有序数组三、441. 排列硬币四、374. 猜数字大小五、367. 有效的完全平方数六、69. x 的平方根 一、81. 搜索旋转排序数组 II 中等 已知存在一个按非降序排列的整数数组 nums &#xff0c;数组中的值不必…

Linux运维_Bash脚本_构建安装ReadLine-6.2.4(setup.py)

Linux运维_Bash脚本_构建安装ReadLine-6.2.4(setup.py) Bash (Bourne Again Shell) 是一个解释器&#xff0c;负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件&#xff0c;并于 1989 年发布的免费软件&#xff0c;作为 Sh (Bourne Shell) 的替代品。 您可…

【Linux】iftop命令详解

目录 一、iftop简介 二、安装iftop命令 2.1 命令查看测试环境系统信息 2.2 查看iftop版本与命令帮助 三、iftop的基本使用 3.1 直接使用iftop命令 3.2 iftop的显示说明 3.3 指定监控某块网卡 3.4 显示某个网段进出封包流量 3.5 按照流量排序 3.6 过滤显示连接 3.7 …

米酒生产加工污水处理需要哪些工艺设备

米酒生产加工过程中产生的污水是一项重要的环境问题&#xff0c;需要采用适当的工艺设备进行处理。下面将介绍一些常用的污水处理工艺设备。 首先&#xff0c;生产过程中的污水需要进行初级处理&#xff0c;常见的设备包括格栅和砂池。格栅用于去除污水中的大颗粒杂质&#xff…

穿越程序员的迷宫:前端花园、后端洞穴与数据科学的密室

穿越程序员的迷宫&#xff1a;前端花园、后端洞穴与数据科学的密室 当你步入程序员的职业赛道&#xff0c;就像踏入一座错综复杂的迷宫。这座迷宫中&#xff0c;有前端的美丽花园&#xff0c;后端的黑暗洞穴&#xff0c;还有数据科学的神秘密室。每一个转角都可能藏着新的机遇…

金相显微镜(金相镜)主要用于材料金相分析 我国市场集中度较低

金相显微镜&#xff08;金相镜&#xff09;主要用于材料金相分析 我国市场集中度较低 金相显微镜又称为金相镜&#xff0c;是指通过光学放大&#xff0c;对材料显微组织、低倍组织和断口组织等进行分析研究和表征的光学显微镜。金相显微镜通常由目镜、物镜、照明系统、旋转台等…

Unity 和 UE 的 .gitignore 文件

各种.gitignore版本 点击跳转 Unity .gitignore 模版 # This .gitignore file should be placed at the root of your Unity project directory # # Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore # /[Ll]ibrary/ /[Tt]emp/ /[Oo]bj/ /[Bb…

视频监控平台EasyCVR+4G/5G应急布控球远程视频监控方案

随着科技的不断发展&#xff0c;应急布控球远程视频监控方案在公共安全、交通管理、城市管理等领域的应用越来越广泛。这种方案通过在现场部署应急布控球&#xff0c;实现对特定区域的实时监控&#xff0c;有助于及时发现问题、快速响应&#xff0c;提高管理效率。 智慧安防视…