【Linux】编写第一个小程序:进度条

文章目录

  • 1. 预备知识
    • 1.1 简单认识几个函数
      • 1.1.1 sleep()
      • 1.1.2 fflush()
      • 1.1.3 usleep()
      • 1.1.4 memset()
    • 1.2 缓冲区
    • 1.3 回车与换行
  • 2. 编写入门版的进度条
    • 2.1 基本逻辑
    • 2.2 美化效果
    • 2.3 代码实现
    • 2.4 执行效果
  • 3. 编写升级版的进度条
    • 3.1 代码实现
    • 3.2 执行效果

在这里插入图片描述

1. 预备知识

1.1 简单认识几个函数

1.1.1 sleep()

unsigned int sleep(unsigned seconds);
  • 作用:让程序休眠指定秒数,如:sleep(3); //让程序休眠3秒
  • 与 Windows 上的 Sleep() 函数不同
  • 需要包含头文件<unistd.h>

1.1.2 fflush()

int fflush(FILE* stream);
  • 作用:刷新缓冲区
  • 需要传入一个流
  • 需要包含头文件<stdio.h>

1.1.3 usleep()

int usleep(useconds_t usec);
  • 作用:让程序休眠指定微秒,如:usleep(100000); //让程序休眠100000微秒(0.1秒)
  • 1秒 = 1000000微秒
  • 需要包含头文件<unistd.h>

1.1.4 memset()

void* memset(void* ptr, int value, size_t num);
  • 作用:将 ptr 指向的内存块的前 num 个字节设置为指定的 value 值
  • 返回设置后的 ptr
  • 需要包含头文件<string.h>

1.2 缓冲区

直接上代码观察现象

#include <stdio.h>#include <unistd.h>int main(){    printf("you can see me       ");    sleep(3);    return 0;}

执行效果图

在这里插入图片描述

  • 首先要否定上面不切实际的想法,C语言是顺序执行的,所以 printf 函数一定先于 sleep 函数执行。
  • 那为什么 3 秒后才打印到屏幕上呢?当然是因为缓冲区!
  • printf 函数跑完后,输出的字符串是被保存到 C 对 IO 函数提供的一个缓冲区里了,在程序退出的时候,缓冲区中的内容才被刷新到屏幕上
  • 我们需要使用上面讲的 fflush 函数把缓冲区中的内容提前强制刷新到屏幕上,使用方法:fflush(stdout);

1.3 回车与换行

首先我要抛出一个概念:回车和换行是不一样的!

  • 回车( /r ):把光标放到当前行的开始。

在这里插入图片描述

  • 换行( /n ):把光标放到当前位置的下一行。

在这里插入图片描述

  • 所以理论上来讲,‘/n’ 和 ‘/r’ 一起用才是我们理解中的”回车“,即:把光标放到下一行最开始的位置。

2. 编写入门版的进度条

2.1 基本逻辑

  • 进度 1% 打印 1 个字符,回车到开始的位置,刷新缓冲区;
  • 进度 2% 打印 2 个字符,回车到开始的位置,刷新缓冲区;
  • 进度 100% 打印 100 个字符,回车到开始的位置,刷新缓冲区,程序终止。

在这里插入图片描述

2.2 美化效果

  • 进度条主体增加箭头显示
  • 显示进度百分比
  • 添加一个动态的旋转光标

在这里插入图片描述

2.3 代码实现

// porcessbar.h#pragma once#include <stdio.h>#define NUM 103#define Body '='#define Head '>'// version 1void process();
// processbar.c#include "processbar.h"#include <string.h>#include <unistd.h>const char* lable = "|/-//";// version 1void 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(50000);    }    printf("/n");}

2.4 执行效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

3. 编写升级版的进度条

  • 上面的进度条算是一个进度条吗?我们的进度条似乎在一个人玩单机呀,这样的进度条是没有意义的。
  • 进度条的进度应该是依赖于其他应用的,比如下载。
  • 下面我们模拟一个下载环境,并修改进度条,使进度条可以根据下载的进度,同步进行显示进度的工作。

3.1 代码实现

// processbar.h#pragma once#include <stdio.h>#define NUM 103#define Body '='#define Head '>'typedef void (*callback_t)(double);		// 函数指针类型// version 2void process_flush(double rate);
// processbar.c#include "processbar.h"#include <string.h>#include <unistd.h>const char* lable = "|/-//";// version 2: 进度是多少,你进度条能知道吗?另外,什么进度?依附于其他应用的,比如下载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][%.1f%%][%c]/r", buffer, rate, lable[cnt % n]);    fflush(stdout);    buffer[(int)rate] = Body;    if ((int)rate + 1 < 100)    {        buffer[(int)(rate + 1)] = Head;    }    if (rate >= 100.0)    {        printf("/n");    }    cnt++;    cnt %= n;}
// main.c#include "processbar.h"#include <time.h>#include <stdlib.h>#include <unistd.h>// 模拟文件大小#define FILESIZE (1024 * 1024 * 1024)// 模拟一种场景,表示一种下载任务void download(callback_t cb)    // 回调函数的形式{    srand(time(NULL) ^ 1023);   // 这样写只是为了让随机数更随机    int total = FILESIZE;    while (total)    {        usleep(10000);  // 下载动作        int one = rand() % (1024 * 1024);  // 一次下载的大小        total -= one;        if (total < 0)        {            total = 0;        }        // 当前的进度是多少?        int download = FILESIZE - total;        double rate = (download * 1.0 / FILESIZE) * 100.0;        cb(rate);    }}int main(){    download(process_flush);    return 0;}

3.2 执行效果

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


END


来源:春哥技术博客,欢迎分享,转载请注明出处。(欢迎加春哥团队客服微信号:taike668)

本文地址:https://www.cgtblog.com/cgymlt/11181.html
上一篇:基于WordPress开发微信小程序1:搭建Wor      下一篇:安卓手机(微信小程序)抓蓝牙通信数据包