【Linux】LInux下第一个程序:进度条

前言:

        在前面的文章中我们学习了LInux的基础指令

      【Linux】初见,基础指令-CSDN博客【Linux】初见,基础指令(续)-CSDN博客

        学习了vim编辑器【Linux】vim编辑器_linux vim insert-CSDN博客

        学习了gcc/g++【Linux】编译器gcc/g++及其库的详细介绍-CSDN博客

        以及make/makefile【Linux】自动化构建-Make/Makefile-CSDN博客

有了以上知识的铺垫,我们终于可以开始在Linux上编写运行我们的代码,于是我们来到了Linux下的第一个程序:进度条

1.回车换行符 

       大多数人可能觉得"回车换行"这一词指的是同一个东西。但其实回车是回车、换行是换行,这两个有本质区别。

        我们日常使用的回车键合成了"回车"和"换行"功能,这就导致了大家觉得这是一个东西。

回车的符号为:\n
回车的功能是将光标重置到最开始位置

换行的符号为:\r 
换行的功能是将光标下移一行

2.缓冲区问题

什么是缓冲区?

        缓冲区是系统预留的内存区域,其作用是暂时存放输入或输出的数据。引入缓冲区主要是为了平衡高速的 CPU 与低速的 I/O 设备之间的速度差异,进而提升系统的整体性能。

刷新缓冲区?

        通常情况下,数据会先被存储在缓冲区中,只有当缓冲区满、遇到特定的控制字符,或者程序运行结束时,才会将数据真正写入目标设备。不过,在某些特定场景下,可能需要手动刷新缓冲区,以确保数据能及时输出。

举例:

//代码1
#include<stdio.h>
#include<unistd.h>
int main()
{printf("hello\n");                                                                                                                                       sleep(3);    
}//代码2
#include<stdio.h>
#include<unistd.h>
int main()
{                                                                                                                            printf("hello");sleep(3);    
}

运行代码1:我们可以看到显示屏上马上显示出"hello",然后停滞3秒结束程序

运行代码2:我们看到是恰恰相反,先停滞3秒后打印出"hello",然后结束程序

这个就是缓冲区的问题:"\n"可以马上刷新缓冲区,所以代码1可以马上显示。而没有"\n",就无法马上刷新缓冲区,当整个程序结束后系统自动刷新,显示"hello"

那如何使其马上刷新?

fflush(stdout)

3.预备代码

先创建文件夹,并在文件夹中创建相应的.c .h文件

hyc@hcss-ecs-4ce7:~$ mkdir progress
hyc@hcss-ecs-4ce7:~$ cd progress
hyc@hcss-ecs-4ce7:~/progress$ touch p.c p.h main.c

编写代码,与makefile。进度条只会在一行打印,所以我们不能使用 \n,而是使用 \r,在同一行打印

但是当我们运行代码时,发现并没有显示结果。这是因为当前数据还在缓冲区没有刷新出来,我们使用ffulsh(stdout)使其马上刷新

这时我们可以看到结果:在同一位置上显示

4.进度条代码

4.1首先先看看我们想实现一个什么样子的进度条

4.2代码实现 

我们一步一步来,先实现左侧部分

1.考虑使用字符数组来表示递增的进度条。先将字符数组初始化为 ‘\0’,通过%s打印时遇到 ‘\0’就会停止。

2.通过计数器计数,来计算输出多少符号

3.通过fflush(stdout)立马刷新缓冲区,让我们看到结果

4.通过sleep让我们看到其过程

5.最后为了避免命令行覆盖我们输出的内容,进行换行操作

最后添加一下左右中括号,修改一下细节问题:

打印进度条使用%-100s占位符

sleep有点太慢了,我们可以使用usleep

#include"p.h"
#include<unistd.h>
#include<string.h>void progress_v1()
{char arr[101];memset(arr,'\0',sizeof(arr));int num=0;for(int i=0;i<=101;i++){   arr[num]='X';printf("[%-100s]\r",arr);fflush(stdout);usleep(10000);num++;}   printf("\n");
}  

效果

接下来我们就可以来考虑一下百分比和旋转光标了

1.百分比直接去计算就好了,没什么好说的。

2.旋转光标:我们不要去想复杂了,动态的本质其实就是一帧一帧的静态图像,我们只需要写一个字符数组x,然后不断的打印字符,就可以实现旋转光标了。 

#include<stdio.h>
#include<unistd.h>
#include<string.h>void progress_v1()
{char arr[101];char x[]={'/','-','\\','\0'};memset(arr,'\0',sizeof(arr));int num=0;for(int i=0;i<=101;i++){   arr[num]='X';printf("[%-100s][%.2f][%c]\r",arr,num*1.0/sizeof(arr)*100,x[num%3]);fflush(stdout);usleep(10000);num++;}   printf("\n");
}  

效果演示:

5.模拟真实环境

一个真正的进度条不可能就我们上面写的代码一样自顾自的打印。应该是根据实际情况,一边下载(或其他操作),一边打印进度条。

于是我们实现一个download函数模拟实时下载环境 

total:表示一共想要下载的量

speed:表示单次下载的速度

每下载一次就更新一次进度条

通过实时的下载量来计算进度条中需要打印的个数,以及百分比。 

代码汇总: 

//p.h#include<stdio.h>
void progress_v1();
void progress_v2(double cur,double total);        //p.c#include"p.h"
#include<unistd.h>
#include<string.h>void progress_v1()
{char arr[101];char x[]={'/','-','\\','\0'};memset(arr,'\0',sizeof(arr));int num=0;for(int i=0;i<=101;i++){arr[num]='X';printf("[%-100s][%.2f][%c]\r",arr,num*1.0/sizeof(arr)*100,x[num%3]);fflush(stdout);usleep(10000);num++;}   printf("\n");
}void progress_v2(double cur,double total)
{char arr[101];char x[]={'/','-','\\','\0'};memset(arr,'\0',sizeof(arr));//get the numberint num=(int)(cur*100/total);for(int i=0;i<num;i++){   arr[i]='X';}   printf("[%-100s][%.2f][%c]\r",arr,cur*100/total,x[num%3]);fflush(stdout);
}//main.c#include <stdio.h>
int main()
{printf("Hello world\n");return 0;
}                                                                                                                                         

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

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

相关文章

Web前端基础

### 一、浏览器 火狐浏览器、谷歌浏览器(推荐)、IE浏览器 推荐谷歌浏览器原因&#xff1a; 1、简洁大方,打开速度快 2、开发者调试工具&#xff08;右键空白处->检查&#xff0c;打开调试模式&#xff09; ### 二、开发工具 核心IDE工具 1. Visual Studio Code (VS Code)‌…

C++调试(肆):WinDBG分析Dump文件汇总

目录 1.前言 2.WinDBG中常用的指令 3.分析异常时要关注的信息 4.心得 前言 本篇博客主要针如何使用WinDBG工具调试Dump文件的流程进行一个讲解&#xff0c;具体捕获的Dump文件也是前两节例子中生成的Dump文件。 WinDBG中常用的指令 关于WinDBG调试时常用的指令主要分为以下几种…

SOC-ESP32S3部分:33-声学前端模型ESP-SR

飞书文档https://x509p6c8to.feishu.cn/wiki/YnbmwtqI5iBwE3kHA7AcZ3yTnLf ESP-SR 是乐鑫官方开发的一个音频组件&#xff0c;支持以下模块&#xff1a; 声学前端算法 AFE唤醒词检测 WakeNet命令词识别 MultiNet语音合成&#xff08;目前只支持中文&#xff09; 组件地址&am…

基于vscode,idea,java,html,css,vue,echart,maven,springboot,mysql数据库,在线考试系统

详细视频&#xff1a;【基于vscode,idea,java,html,css,vue,echart,maven,springboot,mysql数据库&#xff0c;在线考试系统-哔哩哔哩】 https://b23.tv/7hwmwmQ

【Linux】shell中的运行流程控制

目录 一.什么是运行流程控制 二.条件允许流程控制--if 2.1.单分支 2.2.双分支 2.3.多分支 if多分支练习 三.循环运行流程控制 无判定循环--for 判断循环--while&#xff0c;until 四.选择运行流程控制 五.自动应答--expect 5.1.固定位置的交互应答 5.2.非固定位置的…

新能源汽车热管理核心技术解析:冬季续航提升40%的行业方案

新能源汽车热管理核心技术解析&#xff1a;冬季续航提升40%的行业方案 摘要&#xff1a;突破续航焦虑的关键在热能循环&#xff01; &#x1f449; 本文耗时72小时梳理行业前沿方案&#xff0c;含特斯拉/比亚迪等8家车企热管理系统原理图 一、热管理为何成新能源车决胜关键&am…

OCR MLLM Evaluation

为什么需要评测体系&#xff1f;——背景与矛盾 ​​ 能干的事&#xff1a;​​ 看清楚发票、身份证上的字&#xff08;准确率>90%&#xff09;&#xff0c;速度飞快&#xff08;眨眼间完成&#xff09;。​​干不了的事&#xff1a;​​ 碰到复杂表格&#xff08;合并单元…

深入解析JVM工作原理:从字节码到机器指令的全过程

一、JVM概述 Java虚拟机(JVM)是Java平台的核心组件&#xff0c;它实现了Java"一次编写&#xff0c;到处运行"的理念。JVM是一个抽象的计算机器&#xff0c;它有自己的指令集和运行时内存管理机制。 JVM的主要职责&#xff1a; 加载&#xff1a;读取.class文件并验…

Python绘图库及图像类型之特殊领域可视化

Python绘图库及图像类型之基础图表-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/148433762?spm1001.2014.3001.5501 Python绘图库及图像类型之高级可视化-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/148450750?spm1001.2014.3001.…

04 APP 自动化- Appium toast 元素定位列表滑动

文章目录 一、toast 元素的定位二、滑屏操作 一、toast 元素的定位 toast 元素就是简易的消息提示框&#xff0c;toast 显示窗口显示的时间有限&#xff0c;一般3秒左右 # -*- codingutf-8 -*- from time import sleep from appium import webdriver from appium.options.an…

C/C++ OpenCV 矩阵运算

C/C OpenCV 矩阵运算详解 &#x1f4a1; OpenCV 是一个强大的开源计算机视觉和机器学习库&#xff0c;它提供了丰富的矩阵运算功能&#xff0c;这对于图像处理和计算机视觉算法至关重要。本文将详细介绍如何使用 C/C 和 OpenCV 进行常见的矩阵运算。 矩阵的创建与初始化 在进…

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…

USB扩展器与USB服务器的2个主要区别

在现代办公和IT环境中&#xff0c;连接和管理USB设备是常见需求。USB扩展器&#xff08;常称USB集线器&#xff09;与USB服务器&#xff08;如朝天椒USB服务器&#xff09;是两类功能定位截然不同的解决方案。前者主要解决物理接口数量不足的“近身”连接扩展问题&#xff0c;而…

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…

验证负载均衡与弹性伸缩

什么是弹性伸缩&#xff08;Auto Scaling&#xff09;&#xff1f; 弹性伸缩是指 云计算平台根据实时负载自动调整计算资源&#xff08;如服务器实例、容器Pod&#xff09;数量&#xff0c;以确保系统在高峰时保持稳定&#xff0c;在低谷时节省成本。 什么时候会触发弹性伸缩&…

区分viewmodel和model职责的方法

gpt回答挺好的&#xff0c;我就分享一下。 1. 最经典的一句话区分 Model&#xff08;Repository/数据层&#xff09;&#xff1a;只负责**“数据获取/存储/持久化”和“核心业务算法”**&#xff0c;不依赖UI层和Android框架&#xff0c;可以脱离界面独立存在。 ViewModel&…

C语言数据结构笔记3:Union联合体+结构体取8位Bool量

本文衔接上文要求&#xff0c;新增8位bool量的获取方式。 目录 问题提出&#xff1a; Union联合体struct结构体(方式1)&#xff1a; Union联合体struct结构体(方式2)&#xff1a; BYTE方式读取&#xff1a; 问题提出&#xff1a; 在STM32单片机的编程中&#xff0c;无法定义Boo…

三种读写传统xls格式文件开源库libxls、xlslib、BasicExcel的比较

最近准备读写传统xls格式文件&#xff0c;而不是较新的xlsx&#xff0c;询问DeepSeek有哪些开源库&#xff0c;他给出了如下的简介和建议&#xff0c;还给出了相应链接&#xff0c;不过有的链接已失效。最后还不忘提醒&#xff0c;现在该用xlsx格式了。 以下是几个可以处理传统…

从测试角度看待CI/CD,敏捷开发

什么是敏捷开发&#xff1f; 是在高强度反馈的情况下&#xff0c;短周期&#xff0c;不断的迭代产品&#xff0c;满足用户需求&#xff0c;抢占更多的市场 敏捷开发是什么&#xff1f; 是一种产品快速迭代的情况下&#xff0c;降低出错的概率&#xff0c;具体会落实到公司的…

figma MCP + cursor如何将设计稿生成前端页面

一、准备工作 figma MCP需要通过figma key来获取设计稿权限&#xff0c;key的生成步骤如下 1. 打开figma网页版/APP&#xff0c;进入账户设定 2. 点击生成token 3. 填写内容生成token(一定要确认复制了&#xff0c;不然关闭弹窗后就不会显示了) 二、配置MCP 4. 进入到cursor…