【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.c
    gcc -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_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");
}

//模拟下载单个文件
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_count
    
    while (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函数可以灵活地与不同的进度条更新函数配合使用。

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【VueUse】重新定义状态管理在 Vue 中的体验

在 Vue 生态系统中&#xff0c;状态管理一直是开发者们关注的焦点之一。而随着 VueUse 的出现&#xff0c;我们迎来了一种全新的方式来处理状态管理&#xff0c;它让我们能够以更简单、更灵活的方式来管理应用程序的状态。 在本文中我们将深入探讨 VueUse 中与状态管理相关的内…

第一篇【传奇开心果系列】Python深度学习库技术点案例示例:深度解读深度学习在自动驾驶领域的应用

传奇开心果博文系列 系列博文目录Python深度学习库技术点案例示例系列 博文目录前言一、深度学习在自动驾驶方面的应用介绍二、目标检测和识别示例代码三、路况感知示例代码四、行为预测示例代码五、路径规划示例代码六、自动驾驶控制示例代码七、感知融合示例代码八、高精度地…

基于Springboot的点餐平台

基于SpringbootVue的点餐平台的设计与实现 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringbootMybatis工具&#xff1a;IDEA、Maven、Navicat 系统展示 用户登录 首页展示 菜品信息 菜品资讯 购物车 后台登录 用户管理 菜品分类管理 菜品信息管理 …

npm、yarn与pnpm详解

&#x1f525; npm、yarn与pnpm详解 &#x1f516; 一、npm &#x1f50d; 简介&#xff1a; npm是随Node.js一起安装的官方包管理工具&#xff0c;它为开发者搭建了一个庞大的资源库&#xff0c;允许他们在这个平台上搜索、安装和管理项目所必需的各种代码库或模块。 &#…

【网页在线小游戏源码】

网页在线小游戏源码 效果图部分源码领取源码下期更新预报 效果图 部分源码 index.html <!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <meta id"viewport" na…

零代码编程:下载的PDF文件自动批量重命名

从arxiv或者一些其他网站下载的PDF文件&#xff0c;标题只是创建时间&#xff0c;看不出里面内容是什么&#xff0c;要一个个打开看非常麻烦。 可以在GPT4中输入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个编写关于重命名PDF文件的Python脚本的任务&…

Llama-7b-Chinese本地推理

Llama-7b-Chinese 本地推理 基础环境信息&#xff08;wsl2安装Ubuntu22.04 miniconda&#xff09; 使用miniconda搭建环境 (base) :~$ conda create --name Llama-7b-Chinese python3.10 Channels:- defaults Platform: linux-64 Collecting package metadata (repodata.js…

机器学习和深度学习-- 李宏毅(笔记与个人理解)Day22

Day 22 Transformer seqence to seqence 有什么用呢&#xff1f; Encoder how Block work 仔细讲讲Residual 的过程&#xff1f; 重构 Decoder - AutoRegressive Mask 由于是文字接龙&#xff0c;所以无法考虑右边的 info 另一种decoder Encoder to Decoder – Cross Attend…

❤mac使用Idea工具

❤mac使用Idea工具 1、安装 直接跳过&#xff0c;文章有 &#xff08;点击跳转&#xff09; 给自己的mac系统上安装java环境 2、使用 快捷键 Command , 系统首选项 设置Idea连接数据库 打开右侧的database&#xff08;或菜单里&#xff09;连接数据库&#xff0c;根据提…

opencv绘制线段------c++

绘制线段 bool opencvTool::drawLines(std::string image_p, std::vector<cv::Point> points) {cv::Mat ima cv::imread(image_p.c_str()); // 读取图像&#xff0c;替换为你的图片路径 cv::Scalar red cv::Scalar(0, 0, 255); // Red color int thickness 2;// 遍…

Vue3 超前版发布,全面拥抱 JSX/TSX

拥抱 JSX/TSX? 我们都知道 Vue 一直主流是使用 template 模板来进行页面的编写。而就在最近,Vue3 的超前项目 Vue Macros 中,发布了 defineRender、setupComponent、setupSFC 这些新的 API,这代表了,以后 Vue3 有可能可以全面拥抱 JSX/TSX 了!! 说这个新 API 之前,我…

2024江苏省考申论新说刷题系统班

2024江苏省考申论新说刷题系统班&#xff0c;针对江苏省考特色&#xff0c;精准指导考生刷题备考。课程系统全面&#xff0c;深入剖析申论题型&#xff0c;提供实战演练机会。通过科学刷题&#xff0c;考生能迅速提升申论能力&#xff0c;为江苏省考成功上岸打下坚实基础。 下…

LangChain的核心模块和实战

主要模型 LLM:对话模型, 输入和输出都是文本Chat Model: 输入输出都是数据结构 模型IO设计 Format: 将提示词模版格式化Predict: langchain就是通过predict的方式调用不同的模型, 两个模型的区别不大, Chat Model 是以LLM为基础的.Parese: langchain还可以对结果进行干预, 得…

Python检测网页文本内容屏幕上的坐标

&#x1f47d;发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【点击进入巨牛的人工智能学习网站】。 Python 检测网页文本内容屏幕上的坐标 在 Web 开发中&#xff0c;经常需要对网页上的文本内…

STM32标准库ADC和DMA知识点总结

目录 前言 一、ADC模数转换器 &#xff08;1&#xff09;AD单通道 &#xff08;2&#xff09;AD多通道 二、DMA原理和应用 &#xff08;1&#xff09;DMA数据转运&#xff08;内存到内存&#xff09; &#xff08;2&#xff09;DMAAD多同道&#xff08;外设到内存&#x…

pnpm install报错 Value of “this“ must be of type URLSearchParams

执行pnpm install的时候就报错Value of “this” must be of type URLSearchParams 由于之前执行没有出现过这个问题&#xff0c;最近在使用vue3所以使用了高版本的node&#xff0c;怀疑是node版本的问题。 解决&#xff1a; 检查node版本 node -v当前使用的是20.11.0的 修改…

银行业ESB架构:构建安全高效的金融信息交换平台

在金融行业&#xff0c;信息交换是银行业务运作的核心。为了实现不同系统之间的数据交互和业务流程的协同&#xff0c;银行通常采用企业服务总线&#xff08;ESB&#xff09;架构。本文将探讨银行业ESB架构的设计理念、关键技术以及实践经验&#xff0c;帮助银行构建安全高效的…

Matlab|基于元模型优化算法的主从博弈多虚拟电厂动态定价和能量管理

1 主要内容 该程序复现《基于元模型优化算法的主从博弈多虚拟电厂动态定价和能量管理》模型&#xff0c;建立运营商和多虚拟电厂的一主多从博弈模型&#xff0c;研究运营商动态定价行为和虚拟电厂能量管理模型&#xff0c;模型为双层&#xff0c;首先下层模型中&#xff0c;构建…

Golang | Leetcode Golang题解之第47题全排列II

题目&#xff1a; 题解&#xff1a; func permuteUnique(nums []int) (ans [][]int) {sort.Ints(nums)n : len(nums)perm : []int{}vis : make([]bool, n)var backtrack func(int)backtrack func(idx int) {if idx n {ans append(ans, append([]int(nil), perm...))return}…

网络安全新挑战:通用人工智能(AGI)等级保护指南

通用人工智能&#xff08;AGI&#xff09;的发展现状及趋势 随着2023年大语言模型应用的划时代突破&#xff0c;以ChatGPT为杰出代表的此类技术犹如一股洪流&#xff0c;彻底颠覆了人类与机器智能交互的疆界&#xff0c;引领通用人工智能&#xff08;AGI&#xff09;步入一个崭…