Linux从0到1——Linux第一个小程序:进度条
Linux从0到1——Linux第一个小程序:进度条
- 1. 输出缓冲区
- 2. 回车和换行的本质
- 3. 实现进度条
- 3.1 简单原理版本
- 3.2 实际工程版本
1. 输出缓冲区
1. 小实验:
编写一个test.c文件,:
#include <stdio.h>
#include <unistd.h>int main()
{printf("你能看见我吗?\n");sleep(1); // 暂停1秒return 0;
}
编译并执行:

先打印,然后暂停一秒结束程序,很好理解。
2. 发现问题:
修改test.c文件内容如下:

再次编译并执行:

发现运行可执行程序后,没有直接打印内容,而是隔了一秒钟,才打印,这好像和我们理解的不太一样,是怎么回事?
我们可以确定的是,一定是printf先执行的,因为C语言代码一定是从上到下运行的,但是现象是字符没有打印。所以,我们可以断定,printf其实早就运行了,只不过在sleep期间,字符串没有被显示出来。在sleep期间,字符串在输出缓冲区当中。
3. 缓冲区:
C/C++语言,会针对标准输出,给我们提供默认的缓冲区(stdout)。我们可以使用fflush函数,可以把一个流强制做刷新(标准输入输出流之后会讲,这里只需要知道它可以刷新输出缓冲区)。
验证:

编译并执行:

那为什么加\n的程序,不需要刷新缓冲区?这是因为\n是一种刷新策略,叫行刷新,默认就有刷新缓冲区的功能。
2. 回车和换行的本质

我们来写一个倒计时程序:
#include <stdio.h>
#include <unistd.h>int main()
{int cnt = 9;while(cnt){printf("%d\n", cnt);cnt--;sleep(1);}return 0;
}
运行一下:

可以发现它是换行打印倒计时,但是我们想让它只在一行打印,并且覆盖掉前一秒的秒数,如何做?\n是换行加回车,我们现在的需求是只回车,不换行,可以通过\r实现,但是\r没有刷新缓冲区的功能。
修改如下:

运行一下:

3. 实现进度条
3.1 简单原理版本
1. 原理讲解:
我们期望的进度条形式如下:

进度条的风格是#,右侧有一个百分数,提示当前具体进度,还有一个旋转光标,可以确定当进度条不动时,进程是还在进行还是卡住了。
- 进度条的实现:第一次输出
#,第二次输出##,一次类推,#越来越多。为了实现图中结果,我们可以通过不断回车,然后覆盖之前的#实现,比如用##覆盖#; - 旋转光标的实现:利用一个常量字符串实现,让字符在
|/-\这几个字符按顺序不断转换,实现旋转效果。
2. 文件准备:

main.c文件是主函数所在文件,进度条的具体实现在process.c文件中,主函数文件通过头文件process.h调用进度条的实现函数,各个文件内容如下(最重要是process.c)。
process.c文件:
#include "process.h"
#include <unistd.h> // sleep的头文件
#include <string.h>#define SIZE 101
#define MAX_RATE 100
#define STYLE '#'
#define STIME 1000*40const char* str="|/-\\"; // 旋转光标void process()
{// version 1int rate = 0;char bar[SIZE] = {0}; // 全部初始化成'\0'int num = strlen(str);while(rate <= MAX_RATE){printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate%num]); // 打印百分号最好用%%fflush(stdout);usleep(STIME); // 单位是u秒bar[rate++] = STYLE;}printf("\n");
}
main.c文件:
#include "process.h" int main()
{process();return 0;
}
process.h文件:
#pragma once#include <stdio.h> void process();
- 编辑
Makefile:

3.2 实际工程版本
无论是任何进度条,一定是和某种任务关联的!
process.c文件:
#include "process.h"const char* str="|/-\\"; // 旋转光标void process_v1()
{// version 1int rate = 0;char bar[SIZE] = {0}; // 全部初始化成'\0'int num = strlen(str);while(rate <= MAX_RATE){printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate%num]); // 打印百分号最好用%%fflush(stdout);usleep(STIME); // 单位是u秒bar[rate++] = STYLE;}printf("\n");
}// 不能一次将进度条打印完毕,否则无法平滑的和场景结合
// 该函数,应该根据rate,自动的打一次
void process_v2(int rate)
{ // version 2static char bar[SIZE] = {0}; int num = strlen(str);if(rate <= MAX_RATE && rate >= 0){printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate%num]); // 打印百分号最好用%%fflush(stdout);bar[rate] = STYLE;}if(rate == MAX_RATE) memset(bar, '\0', sizeof(bar));
}
process.h文件:
#pragma once#include <string.h>
#include <stdio.h>
#include <unistd.h>#define SIZE 101
#define MAX_RATE 100
#define STYLE '#'
#define STIME 1000*40// 定义了一个函数指针类型,其中函数的参数是int,返回值是void
typedef void callback_t(int);void process_v1();
void process_v2(int);
main.c文件:
#include "process.h"#define TARGET_SIZE 1024*1024 // 1MB,下载软件总大小
#define DSIZE 1024*10 // 模拟每次下载的单位大小// 下载软件
void download(callback_t cb)
{int target = TARGET_SIZE; // 下载软件总大小int total = 0; // 目前下载了多少while(total < target){usleep(STIME); // 用简单的休眠时间,模拟本轮下载花费的时间total += DSIZE;int rate = total*100/target;cb(rate); // 传一个比率}printf("\n");
}int main()
{download(process_v2);return 0;
}
我们希望进度条在进度条函数内部循环打印,所以我们采用回调的方式,来进行某种任务的通知,动态更新进度条!
相关文章:
Linux从0到1——Linux第一个小程序:进度条
Linux从0到1——Linux第一个小程序:进度条 1. 输出缓冲区2. 回车和换行的本质3. 实现进度条3.1 简单原理版本3.2 实际工程版本 1. 输出缓冲区 1. 小实验: 编写一个test.c文件,: #include <stdio.h> #include <unistd.h…...
软件工程师,是时候了解下Rust编程语言了
背景 2024年年初,美国政府发布了一份网络安全报告,呼吁软件开发人员停止使用容易出现内存安全漏洞的编程语言,比如:C和C,转而使用内存安全的编程语言。这份报告由美国网络空间总监办公室 (ONCD) 发布,旨在落…...
SSL---VPN
文章目录 目录 一.SSL-VPN概述 优点 二.SSL协议的工作原理 三.虚拟网关技术 用户认证方式 本地认证 服务器认证: 证书匿名认证 Web代理 Web-link和Web改写 端口转发 网络扩展(允许UDP协议) 总结 一.SSL-VPN概述 SLL VPN是一种基于HTTPS&am…...
Chrome 跨域问题CORS 分析
先叠个甲,有错误,望沟通指正! 文章目录 1.什么是跨域报错2.为什么postman可以,浏览器访问就不行?根本原因是什么?2.1浏览器是依据什么来报错跨域的? 3.常规解决方案的分析方案1.通过代理解决方案2.被请求的B域的服务端开启Access-Control-Allow-Origin返回头的支持方案3.通…...
GPU性能测试中的张量和矩阵运算
正文共:888 字 7 图,预估阅读时间:1 分钟 前面我们使用PyTorch将Tesla M4跑起来之后(成了!Tesla M4Windows 10AnacondaCUDA 11.8cuDNNPython 3.11),一直有个问题,那就是显存容量的问…...
Linux运维_Bash脚本_编译安装FreeRDP-3.3.0
Linux运维_Bash脚本_编译安装FreeRDP-3.3.0 Bash (Bourne Again Shell) 是一个解释器,负责处理 Unix 系统命令行上的命令。它是由 Brian Fox 编写的免费软件,并于 1989 年发布的免费软件,作为 Sh (Bourne Shell) 的替代品。 您可以在 Linux…...
CMake官方教程4--使用表达式生成器
1. 使用表达式生成器产生警告 CMakeList.txt cmake_minimum_required(VERSION 3.15)project(Tutorial VERSION 1.0)add_library(tutorial_compiler_flags INTERFACE) target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)set(gcc_like_cxx "$<COM…...
git for windows
记录,git svn混用,检出代码时出错及解决方案, 执行命令: git svn clone svn_project_url 报错: certificate problem.(R)eject,accept (t)emporarily or accept (p)ermanently 解决: 在弹框中 输入P …...
C++实验 面向对象编程
一、实验目的: 掌握类中静态成员的定义方法,初始化方法,使用方法; 掌握类的友元说明方法,理解友元的使用特点 二、实验内容: 1、编写程序,统计某旅馆住宿客人的总数,要求输入客人…...
VC++ 设置网卡接口MTU大小
在 Windows C/C 之中一共有三种方法可以设置网卡的MTU大小。 方法一: SetIpInterfaceEntry 法 static bool SetInterfaceMtu2(int interface_index, int mtu) noexcept{PIP_ADAPTER_ADDRESSES pAddresses NULL;ULONG ulBufLen 0;GetAdaptersAddresses(AF_UNSPEC…...
dpdk-19.11 对向量指令的使用情况分析
不同向量指令识别关键字 __m128i sse uint64x2_t neon __m256i avx2 __m512i avx512 vector altivec dpdk 向量收发包函数 支持 arm neno 向量收发包函数的 pmd 驱动 bnxt hns3 i40e ixgbe mlx5 virtio 支持 sse 向量收发包函数的 pmd 驱动 axgbe hinic fm10k bnxt i40e …...
使用CIP采集欧姆龙EtherNet/IP从入门到精通
本文将会从以下几个方面介绍 1.CIP是什么 2.EtherNet/IP通信是什么 3.CIP通信报文解析 4.使用CIP常用的方法和功能介绍(UCMM) 5.自己封装了一个类,只要知道标签名称,和数据类型即可读写数据 6.demo展示 1.CIP是什么 CIP通信…...
企业如何高效管理微信里的客户?
对于企业来说,懂得高效管理微信列表的客户是非常重要的一件事,只有把客户管理好了,才能更好地提高客户的满意度和忠诚度,我们的销售业务才能顺利进行。 那么,应该怎样管理才能算是高效管理呢?下面就给大家…...
怎么在windows系统上查看kylinos的md5、sha1、sha256值
背景 当前信创行业正如火如荼进行中,当下载kylinos镜像到windows系统下,如何核对镜像是否有损坏,确保文件不被篡改,需要使用工具计算md5、sha1、sha256、sha512值,并与出库邮件中的md5比对。 QuickHash GUI软件简介 QuickHash GUI是一款开源代码的哈希工具,注意哈希能够…...
Windows中在C#中使用Dapper和Mysql.Data库连接MySQL数据库
Windows中在C#中使用Dapper和Mysql.Data库连接MySQL数据库 在Windows中使用C#连接Mysql数据库比较简单,可以直接使用MySql.Data库,目前最新版本为:8.3.0。 当然也可以结合MySql.Data和Dapper库一起使用,目前Dapper的最新版本为&a…...
大一专科,物联网专业,变态成长偏方!
最近看到一个大一,物联网专业的学生提问: 印象中,物联网专业2011年才有的,正好是我毕业那年。 我大概看过物联网专业要学的内容,总结下来就是,比软件不如计算机,比硬件知识不如电子。 不知道老师…...
MyBatis入门(JDBC规范,MyBatis,连接池,Lombok)【详解】
目录 一、JDBC规范【了解】 1. JDBC介绍 2. JDBC示例 3. JDBC的问题 二、MyBatis入门【重点】 1. Mybatis是什么 2. Mybatis使用步骤 3. Mybatis入门案例 1.创建SpringBoot工程 2.创建Mapper 3.功能测试 三、连接池【了解】 1. 什么是连接池 2. 有哪些数据库连接池…...
Vue3--数据和方法
data 组件的 data 选项是一个函数。Vue 在创建新组件实例的过程中会自动调用此函数。 data选项通常返回一个对象,然后 Vue 会通过响应性系统将其包裹起来,并以 $data 的形式存储在组件实例中。 <!DOCTYPE html> <html lang"en"&g…...
网络编程面试题
一、什么是IP地址 1.IP地址是主机在网路中的唯一标识,,当主机从一个网络切换到另一个网络时,会更改IP地址,同样的IP地址也是路由器进行路由选择的标识 2.IP地址的分类 IPV4:采用4字节无符号整数存储 IPV6ÿ…...
移动端区分点击和长按
为了适配移动端,图片加入touchstart,touchend,并加了 e.preventDefault() 屏蔽默认菜单。 然而突然发现移动端图片的链接无响应了,PC端没问题。 而且功能需要区分点击和长按。 原生js如何判断移动端的tap,dbltap,lo…...
深度学习在微纳光子学中的应用
深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向: 逆向设计 通过神经网络快速预测微纳结构的光学响应,替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
Kafka入门-生产者
生产者 生产者发送流程: 延迟时间为0ms时,也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于:异步发送不需要等待结果,同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
微服务通信安全:深入解析mTLS的原理与实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...
论文阅读:Matting by Generation
今天介绍一篇关于 matting 抠图的文章,抠图也算是计算机视觉里面非常经典的一个任务了。从早期的经典算法到如今的深度学习算法,已经有很多的工作和这个任务相关。这两年 diffusion 模型很火,大家又开始用 diffusion 模型做各种 CV 任务了&am…...
