Linux小程序——进度条

预备知识

缓冲区

先看下面两段代码

c 复制代码
int main()
{
    printf("hello world\n");
    sleep(2);
    return 0;
}
c 复制代码
int main()
{
    printf("hello world");
    sleep(2);
    return 0;
}

第一段代码会直接显示hello world,然后等待两秒,程序结束。第二段代码,则会先等待两秒,在显示hello world。由此可以得出printf函数已经跑完,输出的字符串一定是被保存了起来,在退出的时候才能刷新出来。输出的字符串被保存的地方就是对应的缓冲区

回车与换行

换行:指的是光标从一行换到另一行的对应位置

回车:指的是光标回到这一行的最前面

回车对应的转义字符为\r

下面先来练习写一个倒计时的代码

c 复制代码
#include <stdio.h>
#include <unistd.h>
int main()
{
    int cnt=10;
    while(cnt)
    {
        printf("%-2d\r", cnt--);
        fflush(stdout);
        sleep(1);
    }
    return 0;
}

fflush函数会直接把缓冲区里的内容刷新到屏幕上


所用到的函数

c 复制代码
#include <unistd.h>
unsigned int sleep(unsigned int seconds);//当程序在运行时,执行到sleep时休眠上seconds秒
c 复制代码
#include <stdio.h>
int fflush(FILE*stream);//强制刷新一个流,(可以将缓冲区里的内容强制刷新到屏幕上)
c 复制代码
#include <unistd.h>
int usleep(useconds_t usec);//休眠的时间单位是微秒

项目源码

processbar.h

c 复制代码
#pragma once 

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define NUM 103
#define Body '='
#define Head '>'

typedef void (*callback_t)(double);

//version 1

void process();

void process_flush(double rate);

processbar.c

c 复制代码
#include "processbar.h"

const char* lable="|/-\\";

void process()
{
    char buffer[NUM];
    memset(buffer, '\0',sizeof(buffer));
    int cnt = 0;
    int n=strlen(lable);
    buffer[0]=Head;
    while(cnt <= 100)
    {
        printf("[%-100s][%-3d%%][%c]\r", buffer, cnt, lable[cnt%n]);
        fflush(stdout);
        buffer[cnt++] = Body;
        if(cnt<100)
            buffer[cnt] = Head;
        usleep(10000);
    }
    printf("\n");
}

char buffer[NUM] = { 0 };
void process_flush(double rate)
{
    static int cnt = 0;
    int n = strlen(lable);
    if(rate <= 1.0)
        buffer[0]=Head;
    printf("[%-100s][%-5.1lf%%][%c]\r", buffer, rate, lable[cnt%n]);
    fflush(stdout);
    buffer[(int)rate] = Body;
    if(rate<99)
    buffer[(int)rate+1] = Head;
    if(rate >= 100.0)
        printf("\n");
    cnt++;
    cnt%=n;
}

main.c

c 复制代码
#include "processbar.h"
#include <time.h>
#include <stdlib.h>

#define FILESIZE 1024*1024*1024

// 模拟下载任务
void download(callback_t cb) // 回调函数的形式
{
    srand(time(NULL));
    int total = FILESIZE;
    while(total)
    {
        usleep(5000);
        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);
    }
}

int main()
{
    //process();
    download(process_flush);
    return 0;
}

makefile

makefile 复制代码
processbar:main.o processbar.o
	gcc -o $@ $^
main.o:main.c
	gcc -c main.c
processbar.o:processbar.c
	gcc -c processbar.c
	
.PHONY:clean
clean:
	rm -rf main.o processbar.o processbar
相关推荐
测试员周周4 小时前
【Appium 系列】第16节-WebView-H5上下文切换 — 混合应用的自动化难点
运维·开发语言·人工智能·功能测试·appium·自动化·测试用例
小鹏linux7 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
在角落发呆7 小时前
Linux转发配置:解锁网络互联的核心密码
linux·运维·网络
齐潇宇8 小时前
Zabbix 7 概述与配置
linux·zabbix·监控告警
裴东青9 小时前
10-实战:RuoYi-Cloud的自动化发布
运维·ci/cd·自动化
江公望9 小时前
Ubuntu htop命令,10分钟讲清楚
linux·服务器
哎呦,帅小伙哦9 小时前
Linux 时间:从原子钟到 clock_gettime 的每一面
linux·运维·服务器
sxgzzn9 小时前
新能源场站数智化转型:基于数字孪生与AI的智慧运维管理平台解析
大数据·运维·人工智能
张小姐的猫9 小时前
【Linux】多线程 —— 线程互斥
linux·运维·服务器·c++
CodeMartain10 小时前
Dify Windows 原生部署(无 Docker、纯本地)
运维·docker·容器