当前位置: 首页 > article >正文

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

请添加图片描述

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

请添加图片描述
Alt
🌈个人主页:是店小二呀
🌈C语言专栏:C语言
🌈C++专栏: C++
🌈初阶数据结构专栏: 初阶数据结构
🌈高阶数据结构专栏: 高阶数据结构
🌈Linux专栏: Linux

🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 请添加图片描述

文章目录

  • 一、知识铺垫
    • 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旅途中有所帮助!

相关文章:

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

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具 &#x1f308;个人主页&#xff1a;是店小二呀 &#x1f308;C语言专栏&#xff1a;C语言 &am…...

【办公类-53-04】20250209Python模仿制作2024学年第二学期校历

背景需求&#xff1a; 马上开学了&#xff0c;又要制作校历&#xff08;删划节假日&#xff09;。之前我都是用网络的图片&#xff0c;然后在PPT里修改。 存在问题&#xff1a; 网络校历是从周日开始的&#xff0c;但日常我们老师做教案&#xff0c;都是默认从周一到周五&…...

11vue3实战-----封装缓存工具

11vue3实战-----封装缓存工具 1.背景2.pinia的持久化思路3.以localStorage为例解决问题4.封装缓存工具 1.背景 在上一章节&#xff0c;实现登录功能时候&#xff0c;当账号密码正确&#xff0c;身份验证成功之后&#xff0c;把用户信息保存起来&#xff0c;是用的pinia。然而p…...

Unity 基础编程

在这个练习中将新建unity脚本&#xff0c;控制player的运动与转动&#xff0c;实现用代码检测碰撞与删除物体。 该练习将应用附件中的项目文件&#xff0c;该文件与Unity快速练习的文件是同一个项目文件。 一、构建Player运动脚本 该部分将构建一个在场景中由玩家控制游戏物…...

Spring Boot接入Deep Seek的API

1&#xff0c;首先进入deepseek的官网&#xff1a;DeepSeek | 深度求索&#xff0c;单击右上角的API开放平台。 2&#xff0c;单击API keys&#xff0c;创建一个API&#xff0c;创建完成务必复制&#xff01;&#xff01;不然关掉之后会看不看api key&#xff01;&#xff01;&…...

介绍下SpringBoot常用的依赖项

Spring Boot 是一个用于快速开发 Spring 应用程序的框架&#xff0c;它通过自动配置和依赖管理简化了开发过程。以下是一些 Spring Boot 项目中常用的依赖项&#xff1a; 1. Spring Boot Starter Web 作用: 用于构建 Web 应用程序&#xff0c;包括 RESTful 服务。依赖项: spr…...

解决 keep-alive 缓存组件中定时器干扰问题

当使用 keep-alive 缓存组件时&#xff0c;组件中的定时器可能会在组件被缓存后继续运行&#xff0c;从而干扰其他组件的逻辑。为了避免这种情况&#xff0c;可以通过以下方法解决&#xff1a; 1. 在组件的 deactivated 钩子中清理定时器 keep-alive 为缓存的组件提供了 acti…...

PostgreSQL插件-pg_stat_statements-安装和使用

文章目录 插件介绍插件安装1.修改配置文件postgresql.conf2.插件相关参数参数默认值参数说明特别注意pg_stat_statements.max参数设置太小日志会有警告 插件使用1.创建插件2.使用插件3.重置数据4.删除插件 可能会出现的问题1.没有编译安装插件2.没有配置shared_preload_librari…...

flutter安卓打包签名

flutter安卓打包签名 1.创建签名文件 keytool -genkeypair -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-aliaskeytool 是一个用于管理密钥和证书的命令行工具&#xff0c;通常与 Java 开发工具包 (JDK) 一起使用。my-release-…...

从Word里面用VBA调用NVIDIA的免费DeepSeekR1

看上去能用而已。 选中的文字作为输入&#xff0c;运行对应的宏即可&#xff1b;会先MSGBOX提示一下&#xff0c;然后相关内容追加到word文档中。 需要自己注册生成好用的apikey Option ExplicitSub DeepSeek()Dim selectedText As StringDim apiKey As StringDim response A…...

JavaScript 中的防抖和节流,它们的区别是什么,以及如何实现?

在前端开发中&#xff0c;防抖&#xff08;Debounce&#xff09;和节流&#xff08;Throttle&#xff09;是两种常用的优化高频率事件处理的技术。 它们能够有效减少事件处理函数的执行次数&#xff0c;从而提升页面性能和用户体验。 下面将详细解释这两种技术的概念、区别、…...

【Kubernetes的SpringCloud最佳实践】Spring Cloud netflix 能否被K8s资源完全替代?

在部署Spring Cloud微服务到Kubernetes&#xff08;K8s&#xff09;时&#xff0c; Spring Cloud netflix 是否需要完全替代&#xff1f;或者可以部分替代&#xff0c;结合使用&#xff1f; 例如&#xff0c;服务发现和负载均衡可以交给K8s处理&#xff0c; 但某些功能如API网关…...

MATLAB中extract 函数用法

目录 语法 说明 示例 从地址中提取邮政编码 提取在数值位置处的字符 extract函数的功能是从字符串中提取子字符串。 语法 newStr extract(str,pat) newStr extract(str,pos) 说明 newStr extract(str,pat) 返回 str 中与 pat 指定的模式匹配的任何子字符串。 如果 s…...

DeepSeek-V3:开源多模态大模型的突破与未来

目录 引言 一、DeepSeek-V3 的概述 1.1 什么是 DeepSeek-V3&#xff1f; 1.2 DeepSeek-V3 的定位 二、DeepSeek-V3 的核心特性 2.1 多模态能力 2.2 开源与可扩展性 2.3 高性能与高效训练 2.4 多语言支持 2.5 安全与伦理 三、DeepSeek-V3 的技术架构 3.1 模型架构 3…...

C语言学习笔记:子函数的调用实现各个位的累加和

在C语言程序学习之初&#xff0c;我们都会学习如何打印 hello world&#xff0c;在学习时我们知道了int main&#xff08;&#xff09;是主函数&#xff0c;程序从main函数开始执行&#xff0c;这是流程控制的一部分内容。在主函数中我们想要实现一些功能&#xff0c;比如求各个…...

docker安装ollama显示超时或失败

正常安装 1、拉取ollma镜像 docker pull ollama/ollama or docker pull docker.1panel.live/ollama/ollama2、运行ollma镜像 docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama3、运行指定大模型:模型仓库参考网站: library (ollama.com…...

grafana面板配置opentsdb

新增面板&#xff1a; 这里add-panel: 如果不是想新增面板而是想新增一行条目&#xff0c;则点击convert to row: 在新增的面板这里可以看到选择数据源 Aggregator&#xff1a;聚合条件&#xff0c;区分下第一行和第二行的aggregator&#xff0c;第一个是对指标值的聚合&…...

iOS AES/CBC/CTR加解密以及AES-CMAC

感觉iOS自带的CryptoKit不好用&#xff0c;有个第三方库CryptoSwift还不错&#xff0c;好巧不巧&#xff0c;清理过Xcode缓存后死活下载不下来&#xff0c;当然也可以自己编译个Framework&#xff0c;但是偏偏不想用第三方库了&#xff0c;于是研究了一下&#xff0c;自带的Com…...

使用Jenkins实现鸿蒙HAR应用的自动化构建打包

使用Jenkins实现鸿蒙HAR应用的自动化构建打包 在软件开发领域&#xff0c;自动化构建是提高开发效率和确保代码质量的重要手段。特别是在鸿蒙&#xff08;OpenHarmony&#xff09;应用开发中&#xff0c;自动化构建更是不可或缺。本文将详细介绍如何使用Jenkins命令行工具实现…...

2025年02月10日Github流行趋势

项目名称&#xff1a;dify 项目地址url&#xff1a;https://github.com/langgenius/dify项目语言&#xff1a;TypeScript历史star数&#xff1a;64707今日star数&#xff1a;376项目维护者&#xff1a;takatost, crazywoola, laipz8200, iamjoel, JohnJyong项目简介&#xff1a…...

Ansible简单介绍及用法

一、简介 Ansible是一个简单的自动化运维管理工具&#xff0c;基于Python语言实现&#xff0c;由Paramiko和PyYAML两个关键模块构建&#xff0c;可用于自动化部署应用、配置、编排task(持续交付、无宕机更新等)。主版本大概每2个月发布一次。 Ansible与Saltstack最大的区别是…...

渗透利器工具:Burp Suite 联动 XRAY 图形化工具.(主动扫描+被动扫描)

Burp Suite 联动 XRAY 图形化工具.&#xff08;主动扫描被动扫描&#xff09; Burp Suite 和 Xray 联合使用&#xff0c;能够将 Burp 的强大流量拦截与修改功能&#xff0c;与 Xray 的高效漏洞检测能力相结合&#xff0c;实现更全面、高效的网络安全测试&#xff0c;同时提升漏…...

HTML-day1(学习自用)

目录 一、HTML介绍 二、常用的标签 1、各级标题&#xff08;h1-h6&#xff09; 2、段落标签&#xff08;p&#xff09; 3、文本容器&#xff08;span&#xff09; 4、图片标签&#xff08;img&#xff09; 5、超链接标签&#xff08;a&#xff09; 6、表格&#xff08;t…...

Vue07

一、Vuex 概述 目标&#xff1a;明确Vuex是什么&#xff0c;应用场景以及优势 1.是什么 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以管理 Vue 通用的数据 (多组件共享的数据)。例如&#xff1a;购物车数…...

Godot开发框架探索#2

前言 距离上次发文又又又隔了很长一段时间。主要原因还是因为思绪在徘徊&#xff0c;最近纠结的点有以下几个&#xff1a;1.渴求一个稳定的Godot开发框架&#xff1b;2.要不要使用更轻量的开发框架&#xff0c;或者直接写引擎&#xff1b; 3.对自己想做的游戏品类拿不定主意。…...

deepseek实现私有知识库

前言 之前写了如何本地部署deepseek&#xff0c;已经可以私有化问答了&#xff0c;本地搭建deepseek实操&#xff08;ollama搭建&#xff0c;docker管理&#xff0c;open-webui使用&#xff09; 其中我觉得最厉害的还是这个模型蒸馏&#xff0c;使我们可以用很低的代价使用大模…...

2.10学习总结

Dijkstra算法求取最短路径 注&#xff1a;迪杰斯特拉算法并不能直接生成最短路径&#xff0c;但是算法将最短路径信息保存在dist数组和path数组中。 dist数组中保存的是起始点到数组下标对应顶点的路径长度&#xff08;累加的结果&#xff09;path数组中保存的是对应path数组…...

【探索未来科技】2025年国际学术会议前瞻

【探索未来科技】2025年国际学术会议前瞻 【探索未来科技】2025年国际学术会议前瞻 文章目录 【探索未来科技】2025年国际学术会议前瞻前言1. 第四届电子信息工程、大数据与计算机技术国际学术会议&#xff08; EIBDCT 2025&#xff09;代码示例&#xff1a;机器学习中的线性回…...

pytest.fixture

pytest.fixture 是 pytest 测试框架中的一个非常强大的功能,它允许你在测试函数运行前后执行一些设置或清理代码。以下是关于 pytest.fixture 的详细介绍: 一、定义与用途 pytest.fixture 是一个装饰器,用于标记一个函数为 fixture。Fixture 函数中的代码可以在测试函数运…...

大模型基本原理(四)——如何武装ChatGPT

传统的LLM存在几个短板&#xff1a;编造事实、计算不准确、数据过时等&#xff0c;为了应对这几个问题&#xff0c;可以借助一些外部工具或数据把AI武装起来。 实现这一思路的框架包括RAG、PAL、ReAct。 1、RAG&#xff08;检索增强生成&#xff09; LLM生成的内容会受到训练…...