Linux进度条实现

Linux进度条实现

  • 1.\r\n
  • 2.缓冲区
  • 3.缓冲区分类
  • 4.进度条实现

🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【Linux的学习】
📝📝本篇内容:\r\n,缓冲区;缓冲区分类;进度条实现
⬆⬆⬆⬆上一篇:循环队列(C语言版)
💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-

1.\r\n

在我们将进度条之前,我们先来谈谈我们以前学习的换行和回车,了解了这个才能更好的完成进度条。
在我们的以前的学习中,认为\n就是简单的换行,即如下图所示
在这里插入图片描述
但是不知道同学们有没有发现一个问题,那就是其实换行,不只是简单的到了下一行,而是到了下一行并且回到了开头,从底层的角度来说,这是回车\t的作用。但是我们在使用的过程中\n就完成了这两步骤,即换行+回车,这是语言的功劳,看下面的演示
在这里插入图片描述
可以发现我们的\n直接换行+回车的功能

2.缓冲区

接下来我们来看一下单纯的\r的作用
在这里插入图片描述
在这里插入图片描述
我们发现程序运行下来好像没有任何的效果,这是为什么?
其实是因为我们的\t是回车,让光标回到了开头,我们的程序执行的又很快,执行完后又需要显示出命令行,因此直接把打印出来的东西给覆盖了。我们来看一下不带回车\t的情况
在这里插入图片描述
在这里插入图片描述
可以看到啥都不带的情况下,命令行直接在打印内容后面显示了,前面带上\t就是让光标回到了开头,从头开始显示,所以说导致了前面一个程序啥都没显示,这就能更好的理解了。接下来我们设置一个睡眠时间,来更好的看清楚它的执行过程
在这里插入图片描述
在这里插入图片描述

我们这个时候发现怎么还是没有显示出来?这就非常奇怪了
这就不得不来讲一下缓冲区,我们的printf()中的内容不是说会直接显示在显示器上的,而是先放到缓冲区中,缓冲区会根据特定的规则进行刷新。我们对于显示器的刷新是行刷新,因此我们并没有进行换行什么的,就只能到程序结束时才会刷新了。不过我们可以使用fflush函数来进行主动刷新缓冲区
在这里插入图片描述
和我们之前说的一样,在睡眠的5秒期间,光标一直显示在开头,因此后续显示命令行就直接覆盖了
我们再来看一下,使用换行的情况下,睡眠期间能否打印出来
在这里插入图片描述
在这里插入图片描述可以看到如果是带了\n,那就达到了显示器的行缓冲区的要求,即使不使用fflush也能立马打印出来
那有的同学会问,如果啥都不带会是什么情况呢?答案是会到程序结束再打印出来,我们来看下面的演示
在这里插入图片描述
在这里插入图片描述
这样的结果是因为虽然并没有换行符来使内容立马打印出来,但是程序结束前,也需要刷新一下缓冲区。
注意:windows下的情况不一定一样,不同的平台对缓冲区的处理不同,在VS下即使没有\n,也能立马打印出来,对于这一点我认为是图形化界面就是为了可视,所以说就直接显示出来了,无需等待

#include <stdio.h>
#include <Windows.h>
int main()
{printf("hello world");Sleep(10000);//毫秒return 0;
}

在这里插入图片描述

3.缓冲区分类

缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲
全缓冲:在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
行缓冲:在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是标准输入(stdin)和标准输出(stdout)。
不带缓冲:也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。
接下来验证一下不带缓冲区和全缓冲区,行缓冲区前面已经讲过了

全缓冲区验证:

#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{FILE *fp = fopen("./log.txt", "a");int i = 0;char str[]="hello";while (i <= 100000){fwrite(str,strlen(str),1,fp);usleep(10000);//0.01秒,usleep()单位是微秒i++;}while(1);return 0;
}

在这里插入图片描述

可以看到我们执行了代码后,右边的显示log.txt操作持续了好几次都没有显示东西出来,过了一会就出现了,这就证明了只有当缓冲区满了后才会刷盘(测试时如果要清空log.txt可以使用>log.txt重定向)
但是这只是语言层面的,在操作系统的系统调用中的IO不是这样的,它有自己的策略

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>
int main()
{umask(0);int fd = open("./log.txt",O_WRONLY|O_CREAT,0666);//使用系统的IOint i = 0;char str[]="hello";while (i <= 100000){write(fd,str,strlen(str));usleep(10000);//0.01秒,usleep()单位是微秒i++;}// while(1);//保证不是因为程序退出而写入的return 0;
}

在这里插入图片描述

不带缓冲区验证:

#include <stdio.h>
#include <unistd.h>
int main()
{fprintf(stderr,"hello world");sleep(5);return 0;
}

在这里插入图片描述

4.进度条实现

在这里插入图片描述
我们要实现的进度条是这样的,如上图
先来看一下第一个版本

// main.cc
#include "progress.hpp"
#include <unistd.h>
int main()
{Run();return 0;
}
//progress.cc
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define BUFF_SIZE 101
#define STYLE '#'
void Run()
{// 1.先定义一个缓冲区来存储进度条char buff[BUFF_SIZE]; // 需要101一个的原因是最后要添加\0// 清空,保证全为0,后续就不需要在进行修改memset(buff, 0, sizeof(buff));//2.设置动态的标志,保证进度条在运行char lable[5]="/|-\\";// 3.显示进度条int i = 0;while (i <= 100){//-100为了保证左对齐,同时剩余位置添加空格,/r是使光标回到开头,覆盖掉上一次的进度条printf("[%-100s][%d%%][%c]\r", buff, i,lable[i%4]);fflush(stdout);usleep(100000);//0.1秒,每0.1秒显示一下进度条,每次进度条都会变化buff[i++]=STYLE;}printf("\n");}
//progress.hpp
#include <iostream>
#include <stdio.h>
#include <string.h>
void Run();

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

来看一下第二个版本

//progress.cc
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#define BUFF_SIZE 102 //102是为了使最后的>能够存储,不至于越界
#define STYLE '='
#define ARR '>'
void Run()
{// 1.先定义一个缓冲区来存储进度条char buff[BUFF_SIZE]; // 需要101一个的原因是最后要添加\0// 清空,保证全为0,后续就不需要在进行修改memset(buff, 0, sizeof(buff));//2.设置动态的标志,保证进度条在运行char lable[5]="/|-\\";// 3.显示进度条int i = 0;while (i <= 100){//-100为了保证左对齐,同时剩余位置添加空格,/r是使光标回到开头,覆盖掉上一次的进度条printf("[%-100s][%d%%][%c]\r", buff, i,lable[i%4]);fflush(stdout);//刷新一下缓冲区,不然会无法正常显示出来usleep(100000);//0.1秒,每0.1秒显示一下进度条,每次进度条都会变化buff[i++]=STYLE;//if(i>100)也可以这样写,就可以不用把BUFF_SIZE设为102,101即可if(i!=100)buff[i]=ARR;//把最后一个显示为>,更加形象}printf("\n");}

这个版本仅仅是让进度条更好看点,如果大家愿意也可以添加颜色,作者就不在这演示了,防止大家在看代码时迷糊
在这里插入图片描述

🌸🌸Linux进度条实现的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

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

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

相关文章

服务器安装ESXI7.0系统及通过离线包方式升级到ESXI8.0

新到了一台物理服务器需要安装系统&#xff0c;项目不急用&#xff0c;先拿来做些实验。 本次实验目标&#xff1a; 1、在物理服务器上安装ESXI7.0系统&#xff1b; 2、通过离线包升级方式将ESXI7.0升级为ESXI8.0。 实验环境准备&#xff1a; 物理服务器1台&#xff0c;型号…

docker日志保留策略设置

docker日志保留策略设置 默认策略 默认情况下&#xff0c;docker使用json-file日志驱动&#xff0c;并且没有设置日志保留时间。 这意味着容器日志会一直保留在宿主机上&#xff0c;直到容器被删除或手动清理。如果不对日志进行限制&#xff0c;可能会导致磁盘空间被耗尽。 …

uniapp+Vue3(<script setup lang=“ts“>)模拟12306城市左右切换动画效果

效果图&#xff1a; 代码&#xff1a; <template><view class"container"><view class"left" :class"{ sliding: isSliding }" animationend"resetSliding">{{ placeA }}</view><view class"center…

MySQL训练营-慢查询诊断问题

慢查询相关参数和建议配置 slow_query_log long_query_time 日志开关&#xff0c;是否记慢查询日志以及超过多长时间判定为慢查询。 查看参数设置&#xff1a; SHOW VARIABLES LIKE ‘slow_query_log’;SHOW VARIABLES LIKE ‘long_query_time’; 实践建议&#xff1a; …

微服务学习-Nacos 注册中心实战

1. 注册中心的设计思路 1.1. 微服务为什么会用到注册中心&#xff1f; 服务与服务之间调用需要有服务发现功能&#xff1b;例如订单服务调用库存服务&#xff0c;库存服务如果有多个&#xff0c;订单服务到底调用那个库存服务呢&#xff08;负载均衡器&#xff09;&#xff0…

Mac 查看 Java SDK 和 Android SDK 的路径

1. Mac 如何查看 JavaSDK的路径 /usr/libexec/java_home -V2. Mac 如何查看 Android SDK 的路径 在 Android Studio 中按 cmd,打开设置&#xff0c;然后如下方式&#xff0c;第三步如果有值就是第三步的信息。 第三步如果没有值&#xff0c;点开Edit&#xff0c;值在下方&…

AI智慧社区--生成验证码

接口文档&#xff1a; 从接口文档中可以得知的信息&#xff1a; 代码的返回格式为json格式&#xff0c;可以将Controlller换为RestController前端发起的请求为Get请求&#xff0c;使用注解GetMapping通过返回的数据类型&#xff0c;定义一个返回类型Result package com.qcby.…

【LeetCode】--- MySQL刷题集合

1.组合两个表&#xff08;外连接&#xff09; select p.firstName,p.lastName,a.city,a.state from Person p left join Address a on p.personId a.personId; 以左边表为基准&#xff0c;去连接右边的表。取两表的交集和左表的全集 2.第二高的薪水 &#xff08;子查询、if…

DRG/DIP 2.0时代下基于PostgreSQL的成本管理实践与探索(下)

五、数据处理与 ETL 流程编程实现 5.1 数据抽取与转换(ETL) 在 DRG/DIP 2.0 时代的医院成本管理中,数据抽取与转换(ETL)是将医院各个业务系统中的原始数据转化为可供成本管理分析使用的关键环节。这一过程涉及从医院 HIS 系统中抽取患者诊疗数据,并对其进行格式转换、字…

数据缺失补全方法综述

数据缺失补全方法综述 摘要1. 引言2. 数据缺失的类型3. 数据缺失补全方法3.1 简单插补方法3.1.1 均值插补3.1.2 中位数插补3.1.3 众数插补3.1.4 前向填充和后向填充3.1.5 线性插值3.1.6 多重插补 3.2 基于模型的插补方法3.2.1 线性回归插补3.2.2 加权回归插补3.2.3 主成分分析&…

算法竞赛之离散化技巧 python

目录 离散化实战演练总结 离散化 不改变数据相对大小的情况下&#xff0c;对数据进行相应的下标映射&#xff0c;即离散化。 例如&#xff1a;【100,200,300,400,500】&#xff0c;离散化后为【1,2,3,4,5】 什么时候可以离散化&#xff1a;当数据只与它们之间的相对大小有关&a…

系统思考—业务协同

最近在和一些客户的沟通中&#xff0c;企业老板都提到一个共同的困惑&#xff1a;每个部门都感觉自己在解决问题&#xff0c;做了正确的事情&#xff0c;但为什么组织的绩效就是没有增长&#xff1f;更糟糕的是&#xff0c;大家都不知道问题到底出在哪里&#xff1f; 在这种情…

Git 详细安装教程以及gitlab添加SSH密钥

目录 一、下载安装 二、gitlab添加SSH密钥 一、下载安装 &#xff08;1&#xff09;去官网下载 找到下载的安装包双击进行安装。 &#xff08;2&#xff09;使用许可声明 双击下载后的 Git-2.47.1.2-64-bit.exe&#xff0c;开始安装&#xff0c;这个界面主要展示了 GPL 第…

编程题-两数相加(中等)

题目&#xff1a; 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这…

电子应用设计方案103:智能家庭AI浴缸系统设计

智能家庭 AI 浴缸系统设计 一、引言 智能家庭 AI 浴缸系统旨在为用户提供更加舒适、便捷和个性化的沐浴体验&#xff0c;融合了人工智能技术和先进的水疗功能。 二、系统概述 1. 系统目标 - 实现水温、水位和水流的精确控制。 - 提供多种按摩模式和水疗功能。 - 具备智能清洁…

【MySQL】 库的操作

欢迎拜访&#xff1a;雾里看山-CSDN博客 本篇主题&#xff1a;【MySQL】 库的操作 发布时间&#xff1a;2025.1.23 隶属专栏&#xff1a;MySQL 目录 库的创建语法使用 编码规则认识编码集查看数据库默认的编码集和校验集查看数据库支持的编码集和校验集指定编码创建数据库验证不…

一位前端小白的2024总结

目录 简要 一、迷茫点的解决 &#xff08;1&#xff09;前端领域该怎么学&#xff1f; &#xff08;2&#xff09;旧技术还需要学吗&#xff1f; &#xff08;3&#xff09;我该学些什么&#xff1f; 二、折磨点的解决 &#xff08;1&#xff09;学技术成果回报太慢怎么…

kettle与Springboot的集成方法,完整支持大数据组件

目录 概要整体架构流程技术名词解释技术细节小结 概要 在现代数据处理和ETL&#xff08;提取、转换、加载&#xff09;流程中&#xff0c;Kettle&#xff08;Pentaho Data Integration, PDI&#xff09;作为一种强大的开源ETL工具&#xff0c;被广泛应用于各种数据处理场景。…

Linux探秘坊-------5.git

1.git介绍 1.版本控制器 为了能够更⽅便我们管理这些不同版本的⽂件&#xff0c;便有了版本控制器。所谓的版本控制器&#xff0c;就是能让你了解到⼀个⽂件的历史&#xff0c;以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统&am…

Linux网络之TCP

Socket编程--TCP TCP与UDP协议使用的套接字接口比较相似, 但TCP需要使用的接口更多, 细节也会更多. 接口 socket和bind不仅udp需要用到, tcp也需要. 此外还要用到三个函数: 服务端 1. int listen(int sockfd, int backlog); 头文件#include <sys/socket.h> 功能: …