【Linux系统编程】进度条的编写

这篇具有很好参考价值的文章主要介绍了【Linux系统编程】进度条的编写。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一,进度条的必备知识

1,缓冲区的粗略介绍

2,回车与换行

二,进度条的初步制作

1,进度条的初步矿建

2,进度条的版本一

3,进度条的版本二


一,进度条的必备知识

1,缓冲区的粗略介绍

        缓冲区是内存的一部分空间,用于临时存储输入和输出的数据。它可分为输入缓冲区和输出缓冲区。每当我们输入数据时都是往输入缓冲区中存放数据,当刷新缓冲区时,数据将会从缓冲区中拿出输入到某个变量中。每当我们输出数据时,系统将会把数据输出到输出缓冲区中,当刷新输出缓冲区时,数据将会从输出缓冲区输出到指定地方。

        其中,缓冲区的刷新时机是不同的。行缓冲会在遇到换行符时刷新,全缓冲会在缓冲区写满时刷新,而无缓冲则没有缓冲区,代表是系统调用。在C/C++中,通常用 fflush(FILE* stream) 来强制刷新指定流的缓冲区。

        C/C++中类似于sleep函数功能控制的就是缓冲区,当系统调用到sleep是,将会被缓冲区暂时保存起来,一旦sleep运行完毕之后缓冲区才刷新。进度条有时控制的就是缓冲区的刷新时间。

2,回车与换行

        “ 回车 ” 是把光标从当前位置直接指向最开头位置。“ 换行 ” 是把光标从当前位置直接指向下一行同一列的位置。我们在C语言阶段常用的 “ \n ” 指的是 换行 + 回车。而 “ \r ” 只表示回车。


二,进度条的初步制作

1,进度条的初步矿建

        首先,我们先来编写进度条的简单倒计时程序,这就需要运用回车和sleep来控制程序的运行。

#include <iostream>
#include <iomanip> //setw的头文件
#include <unistd.h> //usleep()的头文件,对应参数单位为微秒                                             
#include <cstdio>
using namespace std;
int main()
{
    int n = 10;
    while (n >= 0) {
        cout << left << setw(2) << n << '\r'; //跟C语言中printf("%-2d\r", n)效果一样
        fflush(stdout);   //强制刷新输出缓冲区
        n--;
        usleep(500000);    //这里我们控制缓冲时间为0.5秒
    }
    cout << endl;
    return 0;
}

        下一步,要思考进度条的框架设计。这里的进度条将外围用 " = " 表示进度的加载,外围设置了百分比显示加载数据。用 "|/-\" 来表示其中的加载,即顺时针旋转。

2,进度条的版本一

        首先,外面设置一个头文件 "process.h" 进行必要的设置

#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
using namespace std;

#define Body '='   //使用body来表示进度
#define Head '>'   //Head表示目前加载的终点,这里用 ' > ' 表示

void process1();  //进度条函数

        下面,进行进度功能的编写。这里使用 usleep 功能来控制进度的的运行,这里需注意的是输出缓冲区的刷新。

void process1()
{

    //用lable表示进度条的加载
    string lable("|/-\\");  
    string nums;
    int count = 0;
    int lablesize = lable.size();
    nums.push_back(Head);
    while (count <= 100)
    {
        cout << "[" << left << setw(100) << nums << "]";
        cout << "[" << "%" << count << "]";
        cout << "[" << lable[count % lablesize] << "]" << '\r';
        fflush(stdout);
        nums.clear();
        count++;
        nums.append(count, Body);
        if (count < 100)
        {
            nums.push_back(Head);
        }

        //这里我们设置每0.6秒加载一次
        usleep(60000); 
    }
    cout << endl;
}

运行最终结果:

[====================================================================================================][%100][|]

3,进度条的版本二

        进度条一般都是运用在一种应用上,表示应用的加载过程。很显然,版本一的进度条只是无脑运行,不知道程序进度是多少,即没有依附应用进度,比如下载程序,这时的进度条需依附于下载进度来跟进。

        头文件 "process.h" 添加如下:

#include <iostream>
#include <string>
#include <unistd.h>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define Body '='
#define Head '>'
#define Max 103
#define FileSize 1024*1024*1024  //设置FileSize文件内存为1G,表示下载程序的总大小

typedef void (*callback_t)(double);  //利用函数指针来进行封装进度运用


void download(callback_t);  //模拟一种下载进度
void process2(double rate); //进度条跟进程序

        这里,在设置download下载时要将每一次的下载进度传递给进度条让其显示百分比。

void download(callback_t cb)   //利用回调函数的形式设置进度
{
    srand(time(0)*1024);
    int total = FileSize;
    while (total)
    {
        //下面表示一次下载动作
        usleep(10000);
        int one = rand() % (1024 * 1024 * 5);
        total -= one;
        if (total < 0) 
        {
            total = 0;
        }
        //表示当前的进度
        int download = FileSize - total;
        double rate = (download * 1.0 / (FileSize)) * 100.0;
        cb(rate); //每一次进度条的传递
    }
}

进度条设置时要说明以下几点:

        1,我们使用 "|/-\\" 表示进度跟进时是根据下载进度进行的,与当前的进度无关。

        2,进度条的总设置需与下载程序紧紧联系。比如当程序加载完时,“ > ” 进度条中表示进          度运行的就要停止,即删除。

        3,在输出进度运行过程,我们可添加其色彩表示美观,链接:色彩文本的增添

void process2(double rate)
{

    //用lable表示下载任务一直在跟进
    string lable("|/-\\"); 

    //注意,这里要保留之前的进度,需设置静态
    static char buffer[Max] = { 0 };
    static int cnt = 0;
    if (rate <= 1.0)
    {
        buffer[0] = Head;
    }
    printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]);  //设置色彩,这里我们设置高亮/加粗,青色背景,红色字体的色彩

    fflush(stdout);

    //下面控制进度的跟进
    buffer[(int)rate] = Body;
    if ((int)rate + 1 < 100)
    {
        buffer[(int)(rate + 1)] = Head;
    }
    if (rate >= 100.0)
    {
        cout << endl;
    }
    cnt++;
    cnt %= lable.size();
}

总代码如下:

#include "process.h"
//版本一
void process1()
{
    string lable("|/-\\");
    string nums;
    int count = 0;
    int lablesize = lable.size();
    nums.push_back(Head);
    while (count <= 100)
    {
        cout << "[" << left << setw(100) << nums << "]";
        cout << "[" << "%" << count << "]";
        cout << "[" << lable[count % lablesize] << "]" << '\r';
        fflush(stdout);
        nums.clear();
        count++;
        nums.append(count, Body);
        if (count < 100)
        {
            nums.push_back(Head);
        }
        usleep(60000);
    }
    cout << endl;
}
//版本二
void download(callback_t cb)
{
    srand(time(0) * 1024);
    int total = FileSize;
    while (total)
    {
        usleep(10000);
        int one = rand() % (1024 * 1024 * 5);
        total -= one;
        if (total < 0)
        {
            total = 0;
        }
        int download = FileSize - total;
        double rate = (download * 1.0 / (FileSize)) * 100.0;
        cb(rate);
    }
}
void process2(double rate)
{
    static string lable("|/-\\");
    static char buffer[Max] = { 0 };
    static int cnt = 0;
    if (rate <= 1.0)
    {
        buffer[0] = Head;
    }
    printf("\033[1;31;46m[%-100s]\033[0m[%.1lf%%][%c]\r", buffer, rate, lable[cnt % lable.size()]);
    fflush(stdout);
    buffer[(int)rate] = Body;
    if ((int)rate + 1 < 100)
    {
        buffer[(int)(rate + 1)] = Head;
    }
    if (rate >= 100.0)
    {
        cout << endl;
    }
    cnt++;
    cnt %= lable.size();
}
int main()
{
    //process1(); //使用进度条粗略版本一
    download(process2); //使用进度条进化版本二
    return 0;
}

        最后,要说明的是,以上程序都是在Linux系统下运行进行的,在VS或其它编译器下可能会出现错误消息,这时因为不同平台支持的C标准或系统设置不同而造成的差异。文章来源地址https://www.toymoban.com/news/detail-757493.html

到了这里,关于【Linux系统编程】进度条的编写的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Linux】项目自动化构建工具-make和Makefile 的使用和进度条的实现

    什么是makefile 在我们以后的工作环境中,一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作 Linux中提供了自动化

    2024年02月07日
    浏览(57)
  • Linux高并发服务器开发---笔记1(环境搭建、系统编程、多进程)

    0613 首先这整个系列笔记属于笔记①:牛客校招冲刺集训营—C++工程师中的 第四章 笔记。 视频课链接: 视频1:Linux高并发服务器开发(40h); 视频2:第4章 项目制作与技能提升(录播)(26h30min); 视频课3: 第5章 高频考点与真题精讲(录播)中的 5.10-5.13 项目回顾 有个学

    2024年02月15日
    浏览(45)
  • Linux系统编程,使用C语言实现简单的FTP(服务器/客户端)

    前言 跟着上官社长 陈哥花了一个月的时间终于把Linux系统编程学的差不多了,这一个月真的是头疼啊,各种bug,调的真心心累,不过好在问题都解决掉了,在此也感谢一下答疑老师,给我提供了很多的思路,本文章是对前段时间学习Linux,做一个小小的总结,才疏学浅,只学

    2024年02月12日
    浏览(51)
  • 【LInux】简单进度条程序的编写

    在进行进度条的程序的编写之前,还有几个问题需要解决。 第一个问题,先来看两段代码: 对比上面两段代码只有一个 n 的区别。 左边的代码很简单,就是先打印,然后停顿 3 秒,程序退出。 主要问题是,右边的代码,也实先打印,然后停顿 3 秒,程序退出吗? 答案显然

    2024年02月12日
    浏览(34)
  • 【Linux】编写第一个小程序:进度条

    1.1.1 sleep() 作用:让程序休眠指定秒数,如: sleep(3); //让程序休眠3秒 与 Windows 上的 Sleep() 函数不同 需要包含头文件 unistd.h 1.1.2 fflush() 作用:刷新缓冲区 需要传入一个流 需要包含头文件 stdio.h 1.1.3 usleep() 作用:让程序休眠指定微秒,如: usleep(100000); //让程序休眠100000微秒(

    2024年02月02日
    浏览(32)
  • linux并发服务器 —— linux网络编程(七)

    C/S结构 - 客户机/服务器;采用两层结构,服务器负责数据的管理,客户机负责完成与用户的交互;C/S结构中,服务器 - 后台服务,客户机 - 前台功能; 优点 1. 充分发挥客户端PC处理能力,先在客户端处理再提交服务器,响应速度快; 2. 操作界面好看,满足个性化需求; 3.

    2024年02月09日
    浏览(61)
  • Linux高性能服务器编程 学习笔记 第五章 Linux网络编程基础API

    我们将从以下3方面讨论Linux网络API: 1.socket地址API。socket最开始的含义是一个IP地址和端口对(ip,port),它唯一表示了使用TCP通信的一端,本书称其为socket地址。 2.socket基础API。socket的主要API都定义在sys/socket.h头文件中,包括创建socket、命名socket、监听socket、接受连接、发

    2024年02月07日
    浏览(42)
  • 《Linux高性能服务器编程》笔记04

    本文是读书笔记,如有侵权,请联系删除。 参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 I/O复用使得程序能同时监听多个文件描述符,这对提高程序的性能至关重要。通常,网络程序在下列情况下需要使用I/0复用技术: 客户

    2024年01月21日
    浏览(61)
  • 《Linux高性能服务器编程》笔记01

    本文是读书笔记,如有侵权,请联系删除。 参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 □socket地址API。socket最开始的含义是一个IP地址和端口对(ip,port)。它唯一地 表示了使用TCP通信的一端。本书称其为socket地址。 □s

    2024年01月22日
    浏览(49)
  • 《Linux高性能服务器编程》笔记02

    参考 Linux高性能服务器编程源码: https://github.com/raichen/LinuxServerCodes 豆瓣: Linux高性能服务器编程 Linux提供了很多高级的I/O函数。它们并不像Linux基础I/O函数(比如open和read) 那么常用(编写内核模块时一般要实现这些I/O函数),但在特定的条件下却表现出优秀的性 能。本章将讨论

    2024年01月21日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包