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
相关推荐
挖掘狂人6 小时前
当生产环境"变慢",我用这套 perf + strace 30 分钟定位瓶颈
linux·运维·性能优化
傲世仙尊7 小时前
IO流起步-从fopen到文件描述符fd
linux
Rabitebla7 小时前
【Linux系统编程】 指令(二):一条路径是怎么定位到文件的
linux·c++·笔记·学习·算法
人工智能培训7 小时前
大语言模型:从语言理解到通用智能的跃迁
linux·服务器·前端·人工智能
顶点多余7 小时前
9.20 知识点查漏补缺
linux·面试·职场和发展
高级程序源7 小时前
django招聘网站信息爬取与分析系统79704-计算机课程设计、毕业设计
后端·python·mysql·小程序·django·flask·课程设计
阿明68 小时前
Linux进程【Linux】
linux·运维·服务器
Android系统攻城狮8 小时前
Linux Gstreamer深度解析之gst_audio_resampler_update调用流程与实战(三十)
linux·运维·服务器·gstreamer音视频·音视频进阶
qetfw8 小时前
Linux tcpdump 抓包实战:网卡、主机、端口过滤与 PCAP 分析
linux·tcpdump
微信ipad协议开发8 小时前
微信视频号自动化:内容发布与互动的 API 实现
运维·微信