【Linux】从零开始:编写你的第一个Linux进度条小程序

请添加图片描述

Linux相关知识点可以通过点击以下链接进行学习一起加油!
初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G++编译器
make与Makefile自动化构建GDB调试器与Git版本控制工具

文章目录

  • 一、知识铺垫
    • 1.1 回车与换行概念
    • 1.2 缓冲区
  • 二、实现简单倒计时
  • 三、进度条
    • 3.1 Verrsion1:进度条实现
    • 3.2 下载场景
      • 3.2.1 Main.c
      • 3.2.2 Version2:进度条实现

在Linux编程的学习过程中,制作一个进度条小程序是入门的好选择。本教程将从零开始,带你轻松实现第一个Linux进度条,感受编程的乐趣与成就

一、知识铺垫

1.1 回车与换行概念

在这里插入图片描述

  • 回车】:回到该行首位置
  • 换行】:跳转到下一行

在编程中,转义字符\r表示回车符,将光标移动到行首,而\n表示换行符,将光标移动到下一行首。其中\n完成了两种行为:换行和回车。

1.2 缓冲区

在计算机中,缓冲区是一个临时存储区域,用于存放数据以便于处理。

在显示器上下文中,缓冲区主要指的是显存(视频内存),用于存储即将显示的图像或文本内容。这样,系统可以先将所有待显示的数据加载到缓冲区,然后一次性地将其刷新到屏幕上,以提高显示效率和流畅度。

在这里插入图片描述

二、实现简单倒计时

#include <stdio.h>
#include <unistd.h>int main()
{int cnt = 9;while (cnt >= 0){printf("%d\r", cnt);cnt--;sleep(1);}return 0;
}

实现一个简单动态效果的倒计时,动态效果就是在同一个位置不断数据进行刷新,达到动态效果。代码转义字符部分,不采用\n,而是\r。由于\n会换行,无法达到同一位置不断数据进行刷新的目的,而\r会在本行返回行首。

数据没有显示

由于存在 \r 转义字符,虽然数据会被打印出来,但光标会被移回到行的最左侧。这意味着后续打印的内容将覆盖当前行的开头部分。(打印-光标回到行首-打印覆盖)

fflush强制刷新

如果使用\r时数据没有显示,可能是因为终端的刷新机制。有时输出缓冲区没有立即刷新。你可以在每次打印后调用fflush(stdout);来强制刷新输出缓冲区。

#include <stdio.h>
#include <unistd.h>int main()
{int cnt = 10;while (cnt >= 0){printf("%2d\r", cnt);fflush(stdout); // 刷新输出缓冲区cnt--;sleep(1);}printf("\n倒计时结束!\n");return 0;
}

数据没有完全被覆盖】:由于字符10到字符0~9中,会出来一个字符没有被覆盖,这里可以通过在d前面填加数据,确保数据被覆盖完全。

三、进度条

设计进度条初步想法:有特殊字符表示进度和目前进度占比及其旋转光标。

在这里插入图片描述
在makefile文件
在这里插入图片描述
makefile文件中,头文件不用出现,头文件本身就在我的当前目前下,目录下进行编译,你的原文件已经证明了,#include这个源文件”是在当前目录下的,对此我们makefile文件不需要存在。@^就是代表整个依赖文件,中间需要空格进行隔开。

3.1 Verrsion1:进度条实现

“Version1是用于搭建大体轮廓”,并不是完善好的版本。

#include"Process bar.h"#define Length 101//设计缓冲区长度,其中为'\0'多开一块空间
#define Style '#'//设计进度条状态,显示特殊字符const char* lable = "|/-\\";
//version1
void ProcessBar()
{char bar[Length];//定义缓冲区memset(bar, '\0', sizeof(bar));//设置缓冲区初始数值,清空缓冲区数据操作int len = strlen(lable);int cnt = 0;while (cnt <= 100){printf("[%100s][%d%%][%c]\r", bar,cnt,lable[cnt%len]);fflush(stdout);bar[cnt++] = Style;usleep(10000);}printf("\n");
}

[\r、fflush部分]:前期工作,在代码部分进行注释说明。这里主要是针对循环体进行说明。首先是\rfflush使用上,该点倒计时有过分享,就是需要使用fflush刷新缓冲区数据,提前将数据进行打印,否则由于\r光标回退,新内容进行覆盖,出现无法观察到数据出现情况。

[usleep函数部分]

  • usleep函数,同sleep函数效果是一致的。由于使用sleep导致程序休眠时间过长,进度条特殊字符缓慢。

在这里插入图片描述

  • usleep在休眠的时间单位叫做:micro second微秒
  • 时间单位转换1秒等于1000毫秒 1毫秒等于1000微秒

[printf输出格式部分]

  • [%-100s]:如果是单纯%s,会导致右括号跟特殊字符增多,而跟着跑。这里选择预留空间,使得特殊字符在预留空间部分进行跑动。由于printf默认字符串输出为右对齐,特殊字符从右向左输出打印,可以使-表示左对齐,解决这个问题。
  • [%3d%%]:添加比例,确保进度条进度卡住,通过旋转光标得知,进度条还是进行。同时添加数字,确保有充足空间。

[const char *lable ="|/-\ \ "] :这里\需要使用\的字面值

3.2 下载场景

由于进度条需要配合场景进行使用,现在我们设计一个下载文件的场景。

3.2.1 Main.c

void download()
{double filesize = 100 * 1024 * 1024 * 1.0;//下载文件总大小double current = 0.0;//当前下载进度double bandwidth = 1024 * 1024 * 1.0;//带宽printf("download begin, current: %lf\n", current);while (current <= filesize){ProcessBar(filesize, current);usleep(100000);current += bandwidth;}printf("\ndownload done, filesize: %lf\n", filesize);
}int main()
{download();return 0;
}

在这里插入图片描述

这里提示信息会将部分进度条冲掉,可以采用\n换行打印。

3.2.2 Version2:进度条实现

#include "Processbar.h"#define Length 101//设计缓冲区长度,其中为'\0'多开一块空间
#define Style '#'//设计进度条状态,显示特殊字符const char* lable = "|/-\\";
//version2
void ProcessBar(double total,double current)
{char bar[Length];//定义缓冲区memset(bar,'\0', sizeof(bar));//设置缓冲区初始数值,清空缓冲区数据操作int len = strlen(lable);int cnt = 0;double rate = (100 * current) / total;//进度int loop_count = (int)rate;//循环次数while (cnt <= loop_count){bar[cnt++] = Style;}printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);fflush(stdout);
}

打印出现卡顿情况

由于ProcessBar在外部会被不断调用,导致多次从头开始打印。这里可以将printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);提取出来。在循环体内,将字符串拼接好,放到缓冲区中,根据外部比例,只需要每次打印一张静态的进度条。

不同风格的代码

如果以后我们想在不改变源代码的基础上,使用其他形式进度条。比如:图形界面版的进度条使用起来,这里可以将函数作为参数,只需要传递函数指针即可。

模拟网络是否良好,可以在外部调用不同大小文件。

在这里插入图片描述

在这里插入图片描述


在这里插入图片描述

以上就是本篇文章的所有内容,在此感谢大家的观看!这里是Linux笔记,希望对你在学习Linux旅途中有所帮助!

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

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

相关文章

【HarmonyOS之旅】基于ArkTS开发(二) -> UI开发二

目录 1 -> 声明式UI开发指导 1.1 -> 开发说明 1.2 -> 创建页面 1.3 -> 修改组件样式 1.4 -> 更新页面内容 2 -> 创建简单视图 2.1 -> 构建Stack布局 2.2 -> 构建Flex布局 2.3 -> 构建食物数据模型 2.4 -> 构建食物列表List布局 2.5 -…

【React】新建React项目

目录 create-react-app基础运用React核心依赖React 核心思想&#xff1a;数据驱动React 采用 MVC体系package.jsonindex.html好书推荐 官方提供了快速构建React 项目的脚手架&#xff1a; create-react-app &#xff0c;目前使用它安装默认是19版本&#xff0c;我们这里降为18…

分多个AndroidManifest.xml来控制项目编译

使用场景 公司项目和我的项目的AndroidManifest.xml混在一起&#xff0c;我需要区分开来编译观察app运行 1.在app/src/main/ 下写多个AndroidManifest.xml AndroidManifest.own.xmlAndroidManifest.com.xml 2.编写powershell脚本 第一对脚本com-build.ps1和reset-com-mani…

linux进程

课本概念&#xff1a;程序的⼀个执行实例&#xff0c;正在执行的程序等内核观点&#xff1a;担当分配系统资源&#xff08;CPU时间&#xff0c;内存&#xff09;的实体。 进程信息被放在一个叫做进程控制块的数据结构中&#xff0c;可以理解为进程属性的集合.课本上称之为PCB&…

Hadoop•安装JDK

听说这里是目录哦 创建目录❤️‍&#x1f525;上传JDK安装包&#x1f497;查看JDK是否上传成功&#x1f498;安装JDK&#x1f496;配置JDK系统环境变量&#x1f493;验证JDK是否安装成功&#x1f49e;分发JDK安装目录&#x1f48c;分发系统环境变量文件&#x1f49d;若显示没有…

[Deep Learning] Anaconda+CUDA+CuDNN+Pytorch(GPU)环境配置-2025

文章目录 [Deep Learning] AnacondaCUDACuDNNPytorch(GPU)环境配置-20250. 引子1. 安装Anaconda1.1 安装包下载&#xff1a;1.2 启用安装包安装1.3 配置(系统)环境变量1.4 验证Anaconda是否安装完毕1.5 Anaconda换源 2. 安装CUDACuDNN2.1 判断本机的CUDA版本2.2 下载适合自己CU…

网络原理(四)—— 网络层、数据链路层 与 DNS

网络层 网络层这里重点介绍 IP 协议&#xff0c;首先先解析 IP 数据包&#xff1a; 先介绍第一行&#xff1a; 4位版本号是指使用了哪一个版本的 IP 协议&#xff0c;这里有 IPV4 和 IPV6 两种协议&#xff0c;现在主要使用的是 IPV4 这一个版本号&#xff0c; IPV6 在国内也…

Redis快速入门店铺营业状态设置

Redis简介 Redis是一种基于内存的键值对&#xff08;K-V&#xff09;数据库。 这意味着它与MySQL数据库类似&#xff0c;都能够用于存储数据&#xff0c;但两者又有着本质的区别。首先两者存储数据的结构不一样&#xff0c;Redis通过键&#xff08;key&#xff09;和值…

Node.js 如何实现文件夹内文件批量重命名

文章目录 一、引言二、Node.js 简介2.1 是什么2.2 优势 三、Node.js 批量重命名原理3.1 涉及的核心模块3.2 关键函数 四、实战步骤4.1 环境搭建4.2 代码实现4.3 代码解释 五、案例分析5.1 场景描述5.2 解决方案 六、可能遇到的问题与解决方法6.1 常见错误6.2 解决方案 七、总结…

MySQL(高级特性篇) 04 章——逻辑架构

一、逻辑架构剖析 &#xff08;1&#xff09;服务器处理客户端请求 那服务器进程对客户端进程发送的请求做了什么处理&#xff0c;才能产生最后的处理结果呢&#xff1f;这里以查询请求为例展示&#xff1a;下面具体展开看一下&#xff1a;Connectors是MySQL服务器之外的客户…

滚动字幕视频怎么制作

在当今的视频创作领域&#xff0c;滚动字幕被广泛应用于各种场景&#xff0c;为视频增添丰富的信息展示和独特的视觉效果。无论是影视剧中的片尾字幕、新闻节目中的资讯滚动&#xff0c;还是综艺节目中的人员与鸣谢信息展示&#xff0c;滚动字幕都发挥着不可或缺的作用。接下来…

源码编译安装httpd 2.4,提供系统服务管理脚本并测试(两种方法实现)

方法一&#xff1a;使用 systemd 服务文件 sudo yum install gcc make autoconf apr-devel apr-util-devel pcre-devel 1.下载源码 wget https://archive.apache.org/dist/httpd/httpd-2.4.46.tar.gz 2.解压源码 tar -xzf httpd-2.4.46.tar.gz 如果没有安装tar 记得先安装…

计算机视觉算法实战——步态识别(主页有源码)

✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ ​ ​​​​​​​​​​​​​​​​​​ 1. 步态识别简介✨✨ 步态识别&#xff08;Gait Recognition&#xff09;是计算机视觉领域中的一个…

2025 年 UI 大屏设计新风向

在科技日新月异的 2025 年&#xff0c;UI 大屏设计领域正经历着深刻的变革。随着技术的不断进步和用户需求的日益多样化&#xff0c;新的设计风向逐渐显现。了解并掌握这些趋势&#xff0c;对于设计师打造出更具吸引力和实用性的 UI 大屏作品至关重要。 一、沉浸式体验设计 如…

Leetcode - 周赛431

目录 一&#xff0c;3411. 最长乘积等价子数组 二&#xff0c;3412. 计算字符串的镜像分数 三&#xff0c;3413. 收集连续 K 个袋子可以获得的最多硬币数量 四&#xff0c;3414. 不重叠区间的最大得分 一&#xff0c;3411. 最长乘积等价子数组 本题数据范围小&#xff0c;直…

深入Android架构(从线程到AIDL)_30 JNI架构原理_Java与C的对接03

目录 2.4 以C结构表达类(class)&#xff0c;并创建对象(object) 认识C函数指针 范例 2.5 在C函数里存取对象的属性(attribute) 范例 2.4 以C结构表达类(class)&#xff0c;并创建对象(object) 认识C函数指针 struct里不能定义函数本身&#xff0c;但能定义函数指针(func…

论文笔记(四十七)Diffusion policy: Visuomotor policy learning via action diffusion(下)

Diffusion policy: Visuomotor policy learning via action diffusion&#xff08;下&#xff09; 文章概括5. 评估5.1 模拟环境和数据集5.2 评估方法论5.3 关键发现5.4 消融研究 6 真实世界评估6.1 真实世界Push-T任务6.2 杯子翻转任务6.3 酱汁倒入和涂抹任务 7. 实际双臂任务…

EasyExcel - 行合并策略(二级列表)

&#x1f63c;前言&#xff1a;博主在工作中又遇到了新的excel导出挑战&#xff1a;需要导出多条文章及其下联合作者的信息&#xff0c;简单的来说是一个二级列表的数据结构。 &#x1f575;️‍♂️思路&#xff1a;excel导出实际上是一行一行的记录&#xff0c;再根据条件对其…

软件测试面试题整理

一、人格相关问题 1、自我介绍结构 姓名工作年限简单介绍上家公司的行业主要负责内容个人优势短期内的职业规划应聘该岗位的原因 2、对未来的发展方向怎么看&#xff1f; 没有标准答案&#xff0c;职业规划来讲&#xff0c;可以分为技术层面和管理层面去说&#xff0c;技术…

.NET framework、Core和Standard都是什么?

对于这些概念一直没有深入去理解&#xff0c;以至于经过.net这几年的发展进化&#xff0c;概念越来越多&#xff0c;越来越梳理不容易理解了。内心深处存在思想上的懒惰&#xff0c;以为自己专注于Unity开发就好&#xff0c;这些并不属于核心范畴&#xff0c;所以对这些概念总是…