【linux】Linux第一个小程序-进度条

1. 预备知识:回车和换行

回车(Carriage Return,CR):

  • 在早期的机械打字机中,回车指的是将打字机的打印头移回到行首的操作,这样打印头就可以开始新的一行的打印。
  • 在ASCII编码中,回车用控制字符CR表示,其编码为\r(即十进制的13)。

换行(Line Feed,LF):

  • 换行是指将打印头向下移动到下一行的操作。
  • 在ASCII编码中,换行用控制字符LF表示,其编码为\n(即十进制的10)。

即:回车,回到当前行的行首,不会切换到下一行,如果接着输出的话,本行以前的内容会被逐一覆盖;
换行,换到当前位置的下一行,而不会回到行首。

在Windows系统中,文本文件的换行符通常是回车加换行(CR+LF,即\r\n)。而在Unix/Linux系统中,换行符仅仅是LF(\n)(Unix/Linux下这个\n就就包括了回车和换行)。

2. 预备知识:缓冲区

#include<stdio.h>
#include<unistd.h>int main()
{printf("hello world!");                                                                                                                                        sleep(3);return 0;
}

在这里插入图片描述

在linux下编译运行以上代码,发现在前三秒"hello world!"并未被打印到屏幕上,三秒之后被打印到屏幕上。那么此前三秒,它被储存到了那里呢?
答案是缓冲区,缓冲区(Buffer)主要应用于提高系统性能和效率。缓冲区通常指的是内存中的一段连续区域,用于临时存储数据,减少CPU、内存和外部设备(如硬盘、网络等)之间的交互次数。当应用程序向文件或设备进行读写操作时,数据会首先被存储到缓冲区中,然后再由缓冲区根据特定的刷新策略将数据写入磁盘或设备中。

缓冲区被刷新到显示器上的几种方式:

  • 程序结束的时候,一般要自动冲刷缓冲区
  • \n
  • 缓冲区满了,自动刷新
  • fflush() 函数强制刷新

3. 进度条

此文件夹下新建一个makefile文件:

processbar: Main.c Processbar.cgcc -o $@ $^         //选项 -o $@ 指定输出文件名,其中 $@ 是一个自动变量,代表当前规则的目标(在这里即为processbar)。而 $^ 是另一个自动变量,表示所有依赖文件的集合(即Main.c和Processbar.c).PHONY: clean
clean:rm -f processbar

这是一个用于将Main.cProcessbar.c源文件编译并链接成名为processbar的可执行文件的简单Makefile

这个Makefile提供了两种操作:
1.运行make processbar以编译并链接Main.cProcessbar.c源文件,生成processbar可执行文件。
2.运行make clean以删除processbar可执行文件,清理项目构建产物。

进度条代码版本一:(仅仅是进度条的模拟)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果void ProcBar();////version 1
void ProcBar()
{char bar[Length];   //进度条的显示长度memset(bar,'\0',sizeof(bar));  //先初始化为'\0'填充清零int len=strlen(lable);int cnt=0;while(cnt<=100)    //使用循环结构,从0迭代到100,每次迭代表示进度的1%{printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%len]);   //用回车并不是换行,每次打印进度条都从当前行头部开始打印fflush(stdout);    //强制刷新标准输出缓冲区,确保进度条立刻显示在屏幕上bar[cnt++]=Style;   //进度条数组bar的相应位置添加进度样式字符usleep(200000);    //用于休眠一段时间,模拟任务执行过程。(休眠单位为微秒)}printf("\n");
}int main()
{ProcBar();return 0;
}

这段C语言代码实现了一个简单的进度条功能,用于模拟某个长时间运行的任务(如文件下载、处理任务等)的进度展示。

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

进度条代码版本二:(模拟一个下载任务,根据下载任务的进度打印进度条)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果void ProcBar();////version 2
////配合场景使用
//进度条每执行一次循环就刷新一次,会出现闪烁(我还挺喜欢这个的)
void ProcBar(double total, double current)    //total代表总任务量(即文件大小),current代表当前已完成的任务量(即已下载的数据量)
{char bar[Length];memset(bar, '\0', sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0) / total;int loop_count = (int)rate;       //计算进度百分比rate和对应的循环次数loop_countwhile (cnt <= loop_count){printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);fflush(stdout);bar[cnt++] = Style;//usleep(200000);  //这个也不需要了,在另一个调它的函数download()中有}//printf("\n");
}//模拟下载单个文件
void download()
{double filesize = 100 * 1024 * 1024 * 1.0; // 文件大小100兆double current = 0.0; // 当前下载量double bandwidth = 1024 * 1024 * 1.0; // 网络带宽1兆printf("download begin, current: %lf\n", current);while (current <= filesize)   //使用一个循环来模拟下载过程,每次迭代都更新current的值,并调用ProcBar函数来更新和显示进度条。{// 打印进度条ProcBar(filesize, current);// 从网络获取数据current += bandwidth;usleep(10000);    //模拟网络下载的速度}printf("\ndownload complete!   filesize:%lf\n", filesize);
}int main()
{// 下载测试(模拟单个文件下载)// download();return 0;
}

这段代码实现了一个简单的进度条功能(ProcBar())和一个模拟单个文件下载的函数(download())。实际使用时,只需将download()中的相关参数替换为实际的下载信息,并调用此函数即可在控制台显示下载进度。

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

进度条代码版本三:(模拟多个下载任务,根据下载任务的进度打印进度条)

#include <string.h>
#include <unistd.h>
#include<stdio.h>#define Length 101
#define Style '#'   //进度条填充样式为'#'字符
const char* lable="|/-\\";  //在进度条前方显示动画效果typedef void(*callback_t)(double,double);  //函数指针  
void ProcBar();//闪烁版
//void ProcBar(double total, double current)    //total代表总任务量(即文件大小),current代表当前已完成的任务量(即已下载的数据量)
//{
//    char bar[Length];
//    memset(bar, '\0', sizeof(bar));
//    int len = strlen(lable);
//
//    int cnt = 0;
//    double rate = (current * 100.0) / total;
//    int loop_count = (int)rate;       //计算进度百分比rate和对应的循环次数loop_count
//
//    while (cnt <= loop_count)
//    {
//        printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);
//        fflush(stdout);
//        bar[cnt++] = Style;
//        //usleep(200000);  //这个也不需要了,在另一个调它的函数download()中有
//    }
//
//    //printf("\n");
//}// version 3
// 配合场景使用
// 每次调用函数时直接将bar拼接起来,循环执行完后再刷新,这样就不会出现闪烁
void ProcBar(double total, double current)
{char bar[Length];memset(bar, '\0', sizeof(bar));int len = strlen(lable);int cnt = 0;double rate = (current * 100.0) / total;int loop_count = (int)rate;       //计算进度百分比rate和对应的循环次数loop_countwhile (cnt <= loop_count){bar[cnt++] = Style;}// 填充完成后,一次性打印出完整的进度条,并刷新输出,避免了闪烁现象printf("[%-100s][%.1lf%%][%c]\r", bar, rate, lable[cnt % len]);fflush(stdout);  
}
//此版本进度条与之前版本不同的是,它在循环中先将进度条字符逐个拼接到bar数组中,待循环完成后一次性刷新输出,从而避免了进度条的闪烁现象。// 模拟下载多个文件
double bandwidth = 1024 * 1024 * 1.0;  // 网络带宽1兆
void download(double filesize, callback_t cb)   // 此处用函数指针也很方便
{double current = 0.0; // 当前下载量printf("download begin, current: %lf\n", current);while (current <= filesize)   //使用一个循环来模拟下载过程,每次迭代都更新当前下载量current,并调用回调函数cb来更新和显示进度条{cb(filesize, current);// 从网络获取数据current += bandwidth;usleep(10000);  //模拟下载速度时,每次迭代都增加bandwidth(网络带宽)的值到current,并使用usleep函数来模拟网络延迟}printf("\ndownload complete!   filesize:%lf\n", filesize);
}int main()
{// 多个文件下载测试download(200 * 1024 * 1024, ProcBar);download(400 * 1024 * 1024, ProcBar);download(50 * 1024 * 1024, ProcBar);download(10 * 1024 * 1024, ProcBar);return 0;
}

这段C代码通过定义一个进度条更新函数ProcBar和一个模拟下载函数download,实现了在控制台中展示动态进度条的功能,并模拟了多个文件的下载过程。通过回调函数的使用,使得download函数可以灵活地与不同的进度条更新函数配合使用。

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

闪烁版演示效果:
在这里插入图片描述

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

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

相关文章

数据库介绍(Mysql安装)

前言 工程师再在存储数据用文件就可以了&#xff0c;为什么还要弄个数据库? 一、什么是数据库&#xff1f; 文件保存数据有以下几个缺点&#xff1a; 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质&#xff1a; 磁…

编译支持播放H265的cef控件

接着在上次编译的基础上增加h265支持编译支持视频播放的cef控件&#xff08;h264&#xff09; 测试页面&#xff0c;直接使用cef_enhancement,里边带着的那个html即可&#xff0c;h265视频去这个网站下载elecard,我修改的这个版本参考了里边的修改方式&#xff0c;不过我的这个…

Blender面操作

1.细分Subdivide -选择一个面 -右键&#xff0c;细分 -微调&#xff0c;设置切割次数 2.删除 -选择一个或多个面&#xff0c;按X键 -选择要删除的是面&#xff0c;线还是点 3.挤出面Extrude -选择一个面 -Extrude工具 -拖拽手柄&#xff0c;向外挤出 -微调&#xff…

Opencv | 边缘提取

目录 一. 边缘检测1. 边缘的定义2. Sobel算子 边缘提取3. Scharr算子 边缘提取4. Laplacian算子 边缘提取5. Canny 边缘检测算法5.1 计算梯度的强度及方向5.2 非极大值抑制5.3 双阈值检测5.4 抑制孤立弱边缘 二. 轮廓信息1. 获取轮廓信息2. 画轮廓 一. 边缘检测 1. 边缘的定义…

自动化爬虫工具:you-get安装与使用

Windows下的安装命令&#xff1a; pip install you-get linux下的安装命令&#xff1a; pip3 install you-get 下载完成后&#xff0c;我们可以看到如下的警告&#xff0c;意思就是这个工具并未被添加到环境变量中&#xff0c;如果我们想在命令行中直接调用&#xff0c;需要…

sql今天学习总结

排序order by&#xff08;默认升序&#xff09; order by id desc(降序排序&#xff09; order by id,number&#xff08;先按id排再按name排序&#xff09; in,not in and or 通配符 where name like "Aa%";选取所有以Aa开头的名字 like "%r" 以r结…

Matlab 使用subplot绘制多个子图,一元拟合

实现效果&#xff1a; clc; clear;filename sri.xlsx; % 确认文件路径data readtable(filename); datavalue data{:,2:end}; datavalue datavalue;fig figure(Position, [0, 0, 1500, 900]); indexString ["(a)","(b)","(c)","(d)&qu…

python自动生成SQL语句自动化

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python自动生成SQL语句自动化 在数据处理和管理中&#xff0c;SQL&#xff08;Structured …

opencv图片绘制图形-------c++

绘制图形 #include <opencv2/opencv.hpp> #include <opencv2/core.hpp> #include <filesystem>bool opencvTool::drawPolygon(std::string image_p, std::vector<cv::Point> points) {cv::Mat ima cv::imread(image_p.c_str()); // 读取图像&#xf…

国外企业使用生成式人工智能实例100

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

将游戏界面与注册/登录界面连接到一起

一、 导包 在注册页面中导入一个import subprocess包 二、 使用代码将其连接到一起 在循环中加入下面这一行代码&#xff0c;用来实现效果 subprocess.run(["python", "game代码.py"]

Linux中的vi与vim:编辑器的王者之争与深度探索

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Linux &#xff1a;从菜鸟到飞鸟的逆袭》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、前言 1、Linux的起源与发展 2、vi与vim的历史与发展 …

符合医药行业规范的液氮罐运输和存储温度监测解决方案

API原料药、冻干物质和人体样本必须在玻璃相中以尽可能低的温度运输和存储。专门的低温容器——干式液氮罐——可通过液氮&#xff08;LN2&#xff09;将温度保持在-196 C。由于温度极低&#xff0c;低温容器的温度数据监测不仅具有挑战性&#xff0c;而且还需要更复杂的过程&a…

【论文阅读】ViTAE:Vision transformer advanced by exploring intrinsic inductive bias

ViTAE:Vision transformer advanced by exploring intrinsic inductive bias 论文地址摘要&#xff1a;简介&#xff1a;3 方法论3.1 重温视觉变压器3.2 ViTAE3.3 缩减单元3.4 Normal cell3.5 模型细节 4 训练4.1 Implementation details4.2 Comparison with the state-of-the-…

云原生Service Mesh服务网格简单介绍

serviceMesh是什么 Service Mesh是一个用于处理服务间通信的基础设施层&#xff0c;旨在实现云原生应用复杂服务拓扑中的可靠请求传递。其基本构成是一组与应用一起部署的轻量级网络代理&#xff0c;这些代理对应用来说是透明的。Service Mesh通过统一的方式来控制和处理服务间…

EasyCVR视频汇聚平台无法自动播放视频的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

Canopen的cia402协议下通过SDO报文控制步进电机

Canopen的cia402协议控制步进电机 硬件搭建软件使用发送写SDO报文格式如下对于0x27、0x22、0x23、0x27、0x2B、0x2F解释简单的驱动器相关参数通常速度模式控制步骤如下 发送数据和驱动器返回数据如下图发送读SDO报文格式如下 硬件搭建 在某宝上随便买个支持CANopen协议的驱动&…

Redis入门到通关之数据结构解析-SkipList

文章目录 ☃️概述☃️总结 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 博客特色&…

网站被SmartScreen标记为不安全怎么办?

在互联网时代&#xff0c;网站的安全性和可信度是用户选择是否继续访问的重要因素之一&#xff0c;然而&#xff0c;网站运营者偶尔会发现使用Edge浏览器访问网站时&#xff0c;会出现Microsoft Defender SmartScreen&#xff08;以下简称SmartScreen&#xff09;提示网站不安全…

文化旅游3D数字孪生可视化管理平台推动文旅产业迈向更加美好的未来

随着数字化、智能化管理成为文旅产业发展的必然趋势&#xff0c;数字孪生公司深圳华锐视点创新性地推出了景区三维可视化数字孪生平台&#xff0c;将线下的实体景区与线上的虚拟世界完美融合&#xff0c;引领智慧文旅新潮流。 我们运用先进的数字孪生、web3D开发和三维可视化等…