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
相关推荐
.生产的驴几秒前
Docker 消息队列RabbitMQ 安装延迟消息插件
运维·spring boot·后端·docker·容器·rabbitmq·java-rabbitmq
金灰4 分钟前
wx小程序渗透思路
网络·windows·安全·小程序·notepad++
微刻时光12 分钟前
好课程:uni-app实战音频小说app小程序
小程序·uni-app
霸道流氓气质14 分钟前
CentOS上使用Mosquitto实现Mqtt主题消息发布和订阅mqtt主题消息连同时间戳记录到文件
linux·运维·mqtt·centos·mosquitto
高危型16 分钟前
CentOS 入门
linux·运维·centos
mit6.82420 分钟前
[Linux#49][UDP] 2w字详解 | socketaddr | 常用API | 实操:实现简易Udp传输
linux·网络·c++·笔记·后端
Zww089126 分钟前
uniapp微信小程序用户授权方法
微信小程序·小程序·uni-app
桃花岛主7030 分钟前
Nginx搭建直播服务器,并用rtmp,http-flv,hls三种模式拉流观看直播的流程
运维·服务器·nginx
醉卧雕龙舫 、1 小时前
Linux中安装maven
linux·运维·maven
不悔哥1 小时前
openwrt wsdd模块介绍
linux·c语言·网络·tcp/ip·智能路由器