【Linux】从0到1实现一个进度条小程序

news2024/9/27 23:33:45

在这里插入图片描述
在这里插入图片描述

个人主页:🍝在肯德基吃麻辣烫
我的gitee:gitee仓库
分享一句喜欢的话:热烈的火焰,冰封在最沉默的火山深处


文章目录

  • 前言
  • 一、理解回车 '\r' 和换行 '\n'
  • 二、初步认识缓冲区
    • 1. 认识第一个函数:sleep
    • 2.观察缓冲区出现的现象
    • 3. 认识第二个函数:fflush
  • 三、开始输出进度条
    • 了解倒计时
    • 准备工作
  • 总结

进度条实现:

在这里插入图片描述


前言

本文讲解如何从0到1实现一个进度条小程序。


一、理解回车 ‘\r’ 和换行 ‘\n’

我们在写作文的时候,写到了一行的结尾,就得另起一行并到开头继续写。在这里插入图片描述

其中,这个另起一行的动作就是"换行"
回到开头的动作就是"回车"

  • "回车"这个动作对应的c语言的转义字符是 ‘\r’
  • "换行"这个动作对应的c语言的转义字符是 ‘\n’

但是,\n其实包含了回车和换行两个动作。
我们的键盘上面的回车键也是同时包含回车和换行两个动作。


二、初步认识缓冲区

1. 认识第一个函数:sleep

sleep(1);

sleep函数的功能是让计算机等待指定秒数(单位:秒)后再继续启动。
知道sleep的功能即可。

还有一个睡眠函数:usleep,它们的功能相同,只不过这个函数的单位是微秒

1秒 = 1000毫秒
1毫秒= 1000微秒

2.观察缓冲区出现的现象

来看第一段代码出现的现象:

  2 #include "process.h"
  3 
  4 int main()
  5 {
  6     printf("Hello Linux\n");
  7     sleep(2);
  8 
  9     return 0;
 10 }        

现象:

在这里插入图片描述
第二段代码:

  2 #include "process.h"
  3 
  4 int main()
  5 {
  6     printf("Hello Linux");
  7     sleep(2);                                                                                                                        
  8 
  9     return 0;
 10 }

现象:

在这里插入图片描述

通过这两段代码以及出现的现象可知:

  • 1.第一段代码是直接弹出 “Hello Linux” 字段后两秒,再弹出指令行。
  • 2.第二段代码是两秒过后,再打印"Hello Linux",并且指令行是紧随其后的。

问:第一个现象是先执行printf函数还是先执行sleep函数?

实际上,c语言是从上往下扫描代码的,所以一定是先执行printf函数。那么,在sleep两秒期间,printf函数去哪了呢?

一定是被保存起来了。

这个保存的东西,就叫做缓冲区

在c语言有一块内存叫做缓冲区

缓冲区是由c语言维护的一块内存空间。

到这里就可以解答第一个现象了,首先执行printf函数,输出Hello Linux,先保存到缓冲区中,2秒后再输出到显示器文件中,由于没有换行,后面则紧跟着指令条。

为什么第二个现象是马上就输出Hello Linux,再睡眠两秒呢?

这是因为'\n'这个换行符,具有刷新缓冲区的功能。

也就是把缓冲区里面的东西给刷掉,让它走它该走的地方,别停留在缓冲区里面了。

至此我们可以解释第二个现象了:Hello Linux字符串其实是先保存到缓冲区中的,然而

遇到'\n'这个换行符刷新后,将该字符串输出到了显示器文件中,再执行2秒休眠,这

才是我们看到的东西。

3. 认识第二个函数:fflush

在c程序中会默认打开三个流:标准输入流,标准输出流,标准错误流。
这里只考虑标准输出流,该流的默认数据是stdout,也就是显示器文件。

fflush函数的功能是:将缓冲区的内容写入到标准输出流。
通俗一点就是将缓冲区的内容打印到屏幕上。

有了这个函数,接下来我们就可以实现进度条小程序了。

三、开始输出进度条

了解倒计时

要实现进度条,首先要知道它每一步要输出什么。
首先讲一讲倒计时,我们见过的倒计时是这样的:
在这里插入图片描述
这里有一个需要注意的地方:

  • 每一个数字都会覆盖上一个数字

就用到开头讲到的'\r'回车符,每次输出数字后,将光标回到当前行开头,再输出,就能将上一个数字覆盖。

具体代码如下:

  2 #include "process.h"
  3 
  4 int main()
  5 {
  6     int cnt = 9;
  7     while(cnt)
  8     {
  9        printf("%d\r",cnt--);
 10        fflush(stdout);                                                                                                               
 11        sleep(1);
 12     }
 13     return 0;
 14 }
~

效果如下:

在这里插入图片描述

准备工作

知道倒计时怎么走后,我们的进度条的过程是类似的:
在这里插入图片描述
输出的过程如上,只是每一次都把数据+1,并输出在当前行,达到一个慢慢增加的效果。(这里为了演示过程,实际上每次输出数据都是输出在同一行)

  • 准备一个buf数组,数组大小为102
    • 将数组的所有元素初始化成'\0',这样每次输入都会遇到'\0'而终止
  • 可以给一个小圆圈光标,const char* lable = "|/-\\",意思是:每增加%1,光标就会变化。(这里有两个"\"是为了将转义字符’‘变成一个单纯的’')
  • 效果如下:
    -
  • 当我们输出进度条时(这个进度条的身体由你来决定),我们应该提前保留100个位置给进度条进行输出。也就是:%s–>%-100s
  • 同理,如开头看到的效果展示,为了输出%(百分号),我们需要两个百分号来输出一个单纯的百分号。

到此,贴出代码,就可以实现进度条啦!

process.h文件

  1                                                                                          
  2 #include <stdio.h>                                                   
  3 #include <unistd.h>                                                  
  4 #include <string.h>                                                                  
  5                                                                                                                                      
  6 void process();   

process.c文件

  1  #include"process.h"                                                                                                                 
  2 #define SIZE 102
  3 #define BODY '='
  4 #define HEAD '>'
  5                 
  6 char bar[SIZE]; 
  7 const char* lable = "|\\-/";
  8                             
  9 void process()              
 10 {             
 11     int cnt = 0;
 12     memset(bar,'\0',sizeof(bar));
 13     char c = HEAD;               
 14     while(cnt<100)               
 15     {             
 16         int len = strlen(lable);
 17         bar[cnt++] = BODY;      
 18         if(cnt < 100)           
 19              bar[cnt] = c;
 20         printf("[%-100s][%d%%][%c]\r",bar,cnt,lable[cnt%len]);
 21         fflush(stdout);                                       
 22         usleep(100000);                                       
 23                        
 24     }                  
 25     printf("\n");
 26 }    

main.c文件

  1 
  2 #include "process.h"
  3 
  4 int main()
  5 {
  6     process();                                                                                                                       
  7     return 0;
  8 }

一个进度条就新鲜出炉啦!


总结

今天的文章讲了如何在Linux上实现一个进度条小程序,做这个进度条小程序的核心是理解’\r’和’\n’两个转义字符,以及缓冲区的概念,理解之后,实现起来就不难啦。

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

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

相关文章

固态继电器:电气开关的革命

简介&#xff1a;在电气工程领域&#xff0c;固态技术的发展为各个领域的显着进步铺平了道路。固态继电器 (SSR) 就是其中一项备受关注的创新。与传统机电继电器不同&#xff0c;SSR 采用固态元件&#xff0c;具有许多优点&#xff0c;例如更高的可靠性、更快的响应时间和增强的…

dvwa靶场通关(十)

第十关&#xff1a;DOM Based Cross Site Scripting (XSS) DOM—based XSS漏洞的产生 DOM—based XSS漏洞是基于文档对象模型Document Objeet Model&#xff0c;DOM)的一种漏洞。DOM是一个与平台、编程语言无关的接口&#xff0c;它允许程序或脚本动态地访问和更新文档内容、…

有效的括号字符串(力扣)动态规划、贪心 JAVA

给你一个只包含三种字符的字符串&#xff0c;支持的字符类型分别是 ‘(’、‘)’ 和 ‘*’。请你检验这个字符串是否为有效字符串&#xff0c;如果是有效字符串返回true 。 有效字符串符合如下规则&#xff1a; 任何左括号 ‘(’ 必须有相应的右括号 ‘)’。 任何右括号 ‘)’ …

postgresql表膨胀处理之pgcompacttable部署及使用

环境&#xff1a; 1&#xff09;redhat-release&#xff1a;CentOS Linux release 7.6.1810 (Core) 2&#xff09;database version&#xff1a;postgresql 14.6 一、添加pgstattuple pgcompacttable工具使用过程中需要依赖pgstattuple&#xff0c;因此需先添加pgstattuple…

[C++]01.基础,数据类型,运算符

01.基础,数据类型,运算符 一.C基础入门1.HelloWorld2.注释3.变量4.常量5.关键字6.命名规则 二.数据类型1.整形2.sizeof关键字3.浮点型4.字符型5.转义字符6.字符串型7.布尔类型8.数据的输入 三.运算符1.算数运算符2.赋值运算符3.比较运算符4.逻辑运算符 一.C基础入门 1.HelloWo…

【雕爷学编程】MicroPython动手做(30)——物联网之Blynk 4

知识点&#xff1a;什么是掌控板&#xff1f; 掌控板是一块普及STEAM创客教育、人工智能教育、机器人编程教育的开源智能硬件。它集成ESP-32高性能双核芯片&#xff0c;支持WiFi和蓝牙双模通信&#xff0c;可作为物联网节点&#xff0c;实现物联网应用。同时掌控板上集成了OLED…

力扣 C++|一题多解之动态规划专题(1)

动态规划 Dynamic Programming 简写为 DP&#xff0c;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程。20世纪50年代初&#xff0c;美国数学家贝尔曼&#xff08;R.Bellman&#xff09;等人在研究多阶段决策过程的优化问题时&#xff0c;提出了著名的最优化原理&…

【习题】几道二叉树题目,进来看看你会不?

几道二叉树题目解析 前言正式开始1. 根据二叉树创建字符串&#xff08;力扣606&#xff09;题目描述解析代码 2. 二叉树的层序遍历1&#xff08;力扣102&#xff09;题目描述解析代码 3. 二叉树的层序遍历2&#xff08;力扣107&#xff09;代码 4. 二叉树的最近公共祖先&#x…

接口测试之json中的key获取

在很多情况下我们在进行接口测试的时候都会有获取上个接口返回的json数据中的某个key值&#xff0c;然后下个接口调用这个key值。今天给大家讲解一下针对不同类型的json获取某个key的值。 一、首先是单纯object格式key值获取 获取图中的token的值&#xff0c;首先这是一个响应…

SSM(Vue3+ElementPlus+Axios+SSM前后端分离)【四】

文章目录 SSM(Vue3ElementPlusAxiosSSM前后端分离)--基础环境搭建【四】项目介绍项目功能/界面● SSM 整合项目界面 创建表&#xff0c;使用逆向工程生成Bean、XxxMapper 和XxxMapper.xml1. 创建furns_ssm 数据库和furns 表使用MyBatis Generator 逆向工程生成bean mapper 接口…

基于Jonswap谱的随机波高及波压力生成

内容目录 基于Jonswap谱的随机波高及波压力生成基于Jonswap谱的随机波高及波压力生成 海面高程可视为是平稳高斯随机过程,可通过对波浪谱确定的一系列分量波进行叠加得到。JONSWAP谱是在海洋结构设计和分析中常用的波浪频谱,可以用其来模拟随机波浪。 式中:有义波高H1/3和…

GPIO简介

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 实验步骤 以L…

1. CUDA中的grid和block

1. CUDA中的grid和block基本的理解 Kernel: Kernel不是CPU&#xff0c;而是在GPU上运行的特殊函数。你可以把Kernel想象成GPU上并行执行的任务。当你从主机&#xff08;CPU&#xff09;调用Kernel时&#xff0c;它在GPU上启动&#xff0c;并在许多线程上并行运行。 Grid: 当你…

C高级【day2】

思维导图&#xff1a; 递归实现&#xff0c;输入一个数&#xff0c;输出这个数的每一位&#xff1a; #include<myhead.h>//递归函数 void fun(int num){//num没值不再递归if(0 num){return;}//输出数的最后一位printf("%d\t", num%10);//递归fun(num/10);}…

AI Chat 设计模式:11. 状态模式

本文是该系列的第十一篇&#xff0c;采用问答式的方式展开&#xff0c;问题由我提出&#xff0c;答案由 Chat AI 作出&#xff0c;灰色背景的文字则主要是我的一些思考和补充。 问题列表 Q.1 你知道状态模式吗A.1Q.2 它与有限状态机有什么联系吗&#xff1f;A.2Q.3 知道了&…

Spring:IOC技术、Bean、DI

前言 Spring是一个开源的项目&#xff0c;并不是单单的一个技术&#xff0c;发展至今已形成一种开发生态圈。也就是说我们可以完全使用Spring技术完成整个项目的构建、设计与开发。Spring是一个基于IOC和AOP的架构多层j2ee系统的架构。 SpringFramework&#xff1a;Spring框架…

ROS2学习(四)进程,线程与节点的关系

节点与节点执行器 节点&#xff0c;英文是node,在ROS2中&#xff0c;节点是一个抽象的实体&#xff0c;它可以代表某种或某类特定功能的抽象集合体&#xff0c;它可以存在于进程中&#xff0c;也可以存在于线程中。所有ROS2的基础功能最基础的载体是节点&#xff0c;所有的通信…

mysql的InnoDB和myISAM引擎对比:插入数据

mysql主流引擎是InnoDB和myISAM。两者简单来说&#xff0c;InnoDB是行锁&#xff0c;支持事务&#xff1b;myISAM是表锁&#xff0c;不支持事务。具体理论上的区别&#xff0c;网上有很多说法&#xff0c;我这里不多说了。 这里做了一个试验&#xff0c;插入100w条数据&#x…

redis+token+分布式锁确保接口的幂等性

目录 1.幂等性是什么&#xff1f; 2.如何实现幂等性呢&#xff1f; 1.新增管理员&#xff0c;出弹窗的同时&#xff0c;请求后台。 2.后端根据雪花算法生成唯一标识key&#xff0c;以雪花数为key存到redis。并返回key给前端。 3.前端保存后端传过来的key。 4.前端输入完成…

使用事件侦听器和 MATLAB GUI 查看 Simulink 信号研究

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…