Linux:Linux中第一个小程序_进度条

 前言:

  在日常生活中,我们下载软件,文件,都会都一个进度显示,来告知我们的下载进度,接下来我们可以自己手搓一个进度条,在我们自己写扫雷、贪吃蛇等小游戏时,可以做一个游戏加载进度使用

  在手搓进度条之前,我们需要一些知识作为铺垫,这些知识大家或多说少会有了解,但是我为了让大家更好的了解,我会把这些知识再细讲一下,方便理解。

一、回车换行

  回车换行并不是一个相同的概念,回车是回车,换行是换行,回车换行是两个概念

假设下面两行是我们的一张纸,我们一行只能写四个字,写完之后,光标(红色竖线)停留在第四格内,一般都是直接按回车换行使光标切换到第二行的第一个位置

1、回车概念 

但是如果我们单独回车,光标就会回到第一行的开始

这就是回车

2、换行概念 

如果我们单独换行,光标所在列位置不变,直接切换到下一行

 这就是换行


  所以说我们回车换行,可以说是先回到最左边的位置,再往下跳一行,也可以说是先往下跳一行,再回到最左边的位置

3、相关历史

1、老式键盘

老式键盘就很明确,这个形状就像是先换行再回车

2、老式打字机

在老式打字机的使用时,把纸张放上去,打完一行字的时候,拨动滚轮纸张会往上走完成换行,然后再向左拨动针尖位置完成回车

二、缓冲区 

我们对缓冲区这个名字应该已经很熟悉了,或多或少都都有了解,我在帮助大家回忆一下

我们几段代码来演示缓冲区的存在:

1、printf函数里带\n

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

编译运行后我们查看现象:

现象是先打印出来Hello World,之后等三秒才会退出程序

2、printf函数里不带\n

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

现象是前三秒没有打印

三秒后打印出来

  毫无疑问的是,我们的代码肯定是先执行printf再执行sleep的,之所以打印的东西在sleep后出现的原因就是缓冲区的存在

  我们sleep的三秒中,我们所打印的东西被保存在缓冲区里:

   一开始我们要显示的内容会拷贝一份放在缓冲区里,之后再定期刷新,显示到我们的显示器上

程序结束时,会强制刷新缓冲区,所以我们的Hello World在程序结束时会显示到我们的屏幕上


那为什么我们带上\n就会在sleep之前从缓冲区里刷新到显示器上呢?

刷新缓冲区还有其它三种方式

3、刷新缓冲区

我们在这里只讨论显示器的缓冲区刷新

1、\n

碰到\n立即自动刷新

2、缓冲区满

缓冲区满了自动刷新

3、强制刷新

 认识一个新函数,fflush()

flush就是刷新,他的意思就是刷新特定的输出流

演示:

我在这段代码里用fflush强制刷新,我们会发现,即使printf不带\n,我们要打印的东西依然会在sleep之前显示到我们的屏幕上。

 三、倒计时

我们了解了回车换行与缓冲区的概念,那我们在写进度条前尝试写一个倒计时出来

我们想要的倒计时模样:

倒计时:


代码实现:

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

我们在打印时,每次打印完一个数字,\r都会使光标回到最开始的位置,然后循环再打印会将原来的覆盖 

视频演示:

倒计时演示

四、进度条

做完倒计时,我们开始进入手搓进度条,我们为什么要先做倒计时呢,因为我们要做的进度条,原理和倒计时类似,都是不断地覆盖原来的数据。

我们根据这个GIF,来思考一下我们应该如何制作

1、倒计时模型

大致模型:

2、创建文件 

我们先创建三个文件,头文件,函数实现源文件,测试源文件 

3、项目自动化构建

首先创建一个makefile文件,进入该文件并写入以下代码

 

这样我们在编译时一个make命令就可以完成了

4、代码实现 

1、初版模型实现

1)Processbal.h文件代码
  1 #pragma once
  2 #include<stdio.h>
  3 //void ForTest();
  4 void ProBal();                                                                                                                     

2)Processbal.c文件代码
  1 #include"Processbal.h"
  2 #include<unistd.h>
  3 #include<string.h>
  4 #define Length 101
  5 #define Style '='
  6 const char*lable="|/-\\";
  7 //void ForTest()
  8 //{
  9 //  printf("!!!");
 10 //}
 11 void ProBal()
 12 {
 13   char bar [Length];
 14   memset(bar,'\0',sizeof(bar));
 15   int len=strlen(lable);
 16   int cnt=0;
 17   while(cnt<=100)
 18   {
 19     printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%len]);
 20     fflush(stdout);
 21     bar[cnt++]=Style;                                                                                                              
 22     usleep(50000);
 23   }
 24   printf("\n");
 25 }
3)main.c文件代码
  1 #include"Processbal.h"
  2 int main()
  3 {
  4   ProBal();                                                                                                                        
  5   return 0;
  6 }

 编译运行:

 但是我们这个显然是不够用的,我们只是弄了一个进度条出来,而现实是我们下载的东西是有大小的,包括我们网速大小,我们下载时有对应的带宽,我们呢接下来让他更切合实际。

2、最终版本

1)Processbal.h文件代码
  1 #pragma once
  2 #include<stdio.h>
  3 //void ForTest();
  //函数指针方便我们把函数作为参数传给另一个函数
  4 typedef void (*callback_t)(double,double);
  5 void ProBal(double total,double current); 
2)Processbal.c文件代码
 1 #include"Processbal.h"
  2 #include<unistd.h>
  3 #include<string.h>
  4 #define Length 101
  5 #define Style '='
  6 const char*lable="|/-\\";
  7 //void ForTest()
  8 //{
  9 //  printf("!!!");
 10 //}
 11 void ProBal(double total,double current)
 12 {
 13   char bar [Length];
 14   memset(bar,'\0',sizeof(bar));
 15   int len=strlen(lable);
 16   int cnt=0;
 //   current的占比,每次推动的百分比
 17   double rate=(current*100.0)/total;
 18   int loop_count=(int)rate;
 19   while(cnt<=loop_count)
 20   {                                                                                                                                
 21     bar[cnt++]=Style;
 22   }
 23   printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%len]);
 24   fflush(stdout);
 25 }
3)main.c文件代码
  1 #include"Processbal.h"
  2 #include<unistd.h>
  3 double bandwidth=1024*1024*1.0;
  4 void download(double filesize,callback_t cb)
  5 {
  6   double current=0.0;
  7   printf("download begin,current:%lf\n",current);
  8   while(current<=filesize)
  9   {
 10     cb(filesize,current);
 11     usleep(100000);
 12     current+=bandwidth;
 13   }
 14   printf("\n");                                                                                                                    
 15   printf("download done,filesize:%lf\n",filesize);
 16 }
 17 int main()
 18 {
 //   我们可以自己传自己的目标数据大小进行下载
 19   download(1024*1024*50*1.0,ProBal);
 20   return 0;
 21 }

编译运行:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Hive】6-Hive函数、运算符使用

Hive函数、运算符使用 Hive内置运算符 概述 整体上&#xff0c;Hive支持的运算符可以分为三大类&#xff1a;关系运算、算术运算、逻辑运算。 官方参考文档&#xff1a;https://cwiki.apache.org/confluence/display/Hive/LanguageManualUDF 也可以使用下述方式查看运算符的…

数控机械制造工厂ERP适用范围有哪些

在当今制造业高速发展的背景下&#xff0c;企业资源计划(ERP)系统已成为提升工厂管理效率、实现生产自动化与信息化的关键工具。特别是对于数控机械制造工厂而言&#xff0c;一个合适的ERP系统能够帮助其优化生产流程、提高产品质量、降低生产成本并增强市场竞争力。 1. 生产计…

Windows上安装Go并配置环境变量(图文步骤)

前言 1. 本文主要讲解的是在windows上安装Go语言的环境和配置环境变量&#xff1b; Go语言版本&#xff1a;1.23.2 Windows版本&#xff1a;win11&#xff08;win10通用&#xff09; 下载Go环境 下载go环境&#xff1a;Go下载官网链接(https://golang.google.cn/dl/) 等待…

Dokcer如何容器部署及常见问题

本文讲解通过Docker部署Jenkins过程及遇到的问题。 通过 Docker 部署 Jenkins 使用 Docker 来部署 Jenkins 是一个快速且高效的方式。以下是使用 Docker 部署 Jenkins 的分步骤指南&#xff1a; 1. 安装 Docker 如果你的系统上还没有安装 Docker&#xff0c;请根据操作系统…

VScode实现服务器免密登录(亲测有效)

目录 1 免密步骤1.1 在本地生成密钥1.2 在vscode中下载Remote-SSH1.3 配置SSH文件1.4 在服务器中添加本地公开密钥1.5 远程免密连接试验 2 后记 1 免密步骤 1.1 在本地生成密钥 window R打开命令面板 ssh-keygen1.2 在vscode中下载Remote-SSH 1.3 配置SSH文件 本地密钥的文…

快速查看平台信息脚本(完善中...)

前言&#xff1a; 在熟悉一个平台时&#xff0c;我们经常要去了解这个平台的一些信息&#xff0c;例如架构、CPU核心情况、线程数、用户、内存、磁盘等信息&#xff0c;所以我将这些命令汇总成脚本~方便查看。后面会持续更新&#xff0c;尽量从兼容以及实用地角度修改脚本.....…

JUC并发编程进阶2:CompletableFuture

1 Future接口理论知识复习 Future接口&#xff08;FutureTask实现类&#xff09;定义了操作异步任务执行一些方法&#xff0c;如获取异步任务的执行结果、取消异步任务的执行、判断任务是否被取消、判断任务执行是否完毕等 举例&#xff1a;比如主线程让一个子线程去执行任务…

基于SpringBoot+Vue+uniapp微信小程序的澡堂预订的微信小程序的详细设计和实现

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念&#xff0c;提供了一套默认的配置&#xff0c;让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

Java项目实战II基于Spring Boot的毕业就业信息管理系统设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者&#xff0c;专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 随着高校扩…

Python酷玩之旅_数据分析入门(matplotlib)

导览 前言matplotlib入门1. 简介1.1 Pairwise data1.2 Statistical distributions1.3 Gridded data1.4 Irregularly gridded data1.5 3D and volumetric data 2. 实践2.1 安装2.2 示例 结语系列回顾 前言 翻看日历&#xff0c;今年的日子已划到了2024年10月19日&#xff0c;今天…

【重学 MySQL】七十二、轻松掌握视图的创建与高效查看技巧

【重学 MySQL】七十二、轻松掌握视图的创建与高效查看技巧 创建视图查看视图注意事项 在MySQL数据库中&#xff0c;视图&#xff08;View&#xff09;是一种虚拟表&#xff0c;它基于一个或多个表的数据计算生成结果集&#xff0c;但不存储实际的数据。视图可以简化复杂的查询、…

【OD】【E卷】【真题】【100分】光伏场地建设规划(PythonJavajavaScriptC++C)

题目描述 祖国西北部有一片大片荒地&#xff0c;其中零星的分布着一些湖泊&#xff0c;保护区&#xff0c;矿区; 整体上常年光照良好&#xff0c;但是也有一些地区光照不太好。 某电力公司希望在这里建设多个光伏电站&#xff0c;生产清洁能源对每平方公里的土地进行了发电评…

打印机出现线条和残影情况的主要原因和解决办法

本篇文章主要讲解&#xff0c;打印机出现打印文本&#xff0c;出现线条和残影情况时的解决办法和主要原因的详细解答和处理方法。 作者&#xff1a;任聪聪 日期&#xff1a;2024年10月19日 博客地址&#xff1a;https://rccblogs.com/604.html 打印现象&#xff1a; 说明&…

【virtuoso】sp测电阻

电路测量原理&#xff1a; 1. 电路原理图 2. 仿真设置 点击select&#xff0c;在原理图选择port设置sp扫频范围 3. plot图像 3.1 plot电阻图像 由公式可得&#xff0c;电阻值为阻抗的实部&#xff0c;所以 1. 选择 ZP 2. 绘制real 3. 点击Z11 4. 即可看到电阻值 3.2 plot电容图…

MySQL数据的导出

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

AI写作助手系统盈利模式分析:打造盈利的AI网站

引言 有数据显示&#xff0c;截至2024年初&#xff0c;全球自媒体从业人员数量已超过1.5亿人&#xff0c;其中中国自媒体从业人员数量超过1亿人。这一数字表明&#xff0c;中国自媒体行业拥有庞大的从业者群体。 另一方面&#xff0c;从自媒体行业的发展趋势来看&#xff0c;…

Axure重要元件三——中继器时间排序

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 本节课&#xff1a;中继器数据时间排序 课程内容&#xff1a;数据的升序、降序、重置排序 应用场景&#xff1a;表单数据的排序 案例展示&#xff1a; 步骤一&#xff…

JVM(HotSpot):GC之垃圾回收阶段

文章目录 前言一、标记清除算法(Mark Sweep)二、标记整理算法(Mark Compact)三、复制算法(Copy) 前言 标记出垃圾对象之后&#xff0c;就要进行清理。 那么&#xff0c;如何清理&#xff1f; 这里也有相应的算法。 主要有三种。 一、标记清除算法(Mark Sweep) 原理说明&…

网络学习笔记

一、网络的结构与功能 网络的鲁棒性与抗毁性 如果在移走少量节点后网络中的绝大部分节点仍然是连通的&#xff0c;那么就该网络的连通性对节点故障具有鲁棒性 网络上的动力学 动力系统&#xff1a;自旋、振子或混沌的同步、可激发系统 传播过程&#xff1a;信息传播与拥堵…

【MySQL】mysql导出数据WPS科学计数法解决方法

导出的长串数字 id 会导致科学计数法&#xff0c;修改 WPS 单元格格式可以解决 数字太长还是有问题&#xff0c;最后有个数字会变成 0 可以 直接用 python脚本转换一下 vim convert_txt_xlsx.py #!/usr/bin/env python3# 使用方法# 安装库 # pip3 install pandas openpyxl…