进度条小程序

0.前提知识

  1. 缓冲区:在C/C++语言中,会针对标准输出,给用户提供默认的缓冲区,并且根据一定的机制进行刷新(或者用户自己刷新,比如:在输出缓冲区中使用fflush(stdout)就可以直接刷新输出缓冲区)。值得注意的是,这个缓冲区是语言给出的,而不是系统给出的。

  2. 换行和回车:换行和回车是两回事,但是在C语言的换行符\n中,通常都会包含这两个概念(C语言的\n=换行+回车)a.换行,就是将光标挪至垂直位置的下一行b.回车,就是将光标挪至本行行首

1.简易实现进度条

另外,如果想要改成Windows下运行,那么只需要修改头文件#include #include ,将代码中的usleep()改为Sleep(),并且调整时间参数#define STIME 1000 * 1000#define STIME 100即可成功在windows环境运行下述代码。

    #include 
    #include 
    #include 
    #define SIZE 101
    #define MAX_RATE 100
    #define STYLE '#'
    #define STIME 1000 * 200//1000 * 1000 = 1秒
    const char* str = "\\|/—";
    void process();
    int main()
    {
        process();
        return 0;
    }
    void process()
    {
        int rate = 0;
        char bar[SIZE] = {0};
        int num = strlen(str);
        while(rate <= MAX_RATE)
        {
            printf("[%-100s][%d%%][%c]\r", bar, rate, str[rate % num]);
            fflush(stdout);
            usleep(STIME);//单位为毫秒
            bar[rate++] = STYLE;
        }
        printf("\n");
    }

注意:这个代码要注意shell的屏幕尺寸问题,尺寸不够可能显示乱码。

2.实际开发进度条

这个版本可以好好学,在过程实践中的确有所应用。

进度条通常要和某些任务关联的,比如:下载任务。

    #include 
    #include 
    #include 
    #define SIZE 101
    #define MAX_RATE 100
    #define STYLE '#'
    #define STIME 1000 * 200//1000 * 1000 = 1秒
    const char* str = "-\\|/";
    typedef void (*callback_t)(int);
    void process_plus(int rate)//参数是传递了比例,根据比例来打一段进度条
    {
        static char bar[SIZE];
        int num = strlen(str);//旋转光标字符的长度
        static int i = 0;
        if (rate <= MAX_RATE && rate >= 0)
        {
            printf("[%-100s][%3d%%][%c]\r", bar, rate, str[i % num]);//这里换成i是为了让旋转光标能够运作,不受进度条控制,可以让用户职别这个进度条究竟是卡住了还是仍在加载
            fflush(stdout);
            bar[rate] = STYLE;
            i++;
        }
        if (rate == MAX_RATE)//主要是用在下一次别的程序调用这个函数的时候,避免进度条数组中还有#
        {
            memset(bar, '\0', sizeof(bar));
        }//这样程序可以适用与不同的任务
    }
    void download_1(callback_t cb)//第一个下载任务,正常调用
    {
        int rate = 0;
        while (rate <= 100)
        {
            (*cb)(rate++);//回调函数
            usleep(STIME);//单位为毫秒
        }
        printf("\n");
    }
    void download_2(callback_t cb)//第二个加载任务,模拟还在加载的情况,不是进度条程序卡住
    {
        int rate = 0;
        while (rate <= 100)
        {
            (*cb)(rate++);//回调函数
    
            if (rate == 50)
            {
                rate = 49;
            }
    
            usleep(STIME);//单位为毫秒
        }
        printf("\n");
    }
    int main()
    {
        download_1(process_plus);
        download_2(process_plus);
        return 0;
    }

在上述代码中,我们新增加了一些功能:

  1. 让进度条随着下载任务返回的行号来实时更新进度条

  2. 让旋转光标的选择和进度条的循环变量hile分离开来,使得旋转光标可以独自旋转,而不依赖于进度条。这样就避免了用户无法分辨进度条程序是卡住了,还是处于加载的状态

  3. 我们模拟了两个下载任务交给main()执行,并且内部发送信号rate给进度条,让用户查看两个下载任务的进度,并且第二个下载任务模拟了上面2.的情形

3.拓张功能进度条

我们可以给进度条增添颜色或者加粗、或者替换进度条的字符、亦或者直接使用颜色块来替换进度条字符等等,请发挥您的想象力。

4.补充Windows下的代码

虽然我在开头说明了如何修改成Windows下也可以运行的代码,但是我担心您对开头那段话有所误解,因此特意重新修改为在Windows下运行的代码。

    #include 
    #include 
    //#include 
    #include 
    #define SIZE 101
    #define MAX_RATE 100
    #define STYLE '#'
    #define STIME 100//1000 * 1000 = 1秒
    const char* str = "-\\|/";
    typedef void (*callback_t)(int);
    void process_plus(int rate)//参数是传递了比例,根据比例来打一段进度条
    {
        static char bar[SIZE];
        int num = strlen(str);//旋转光标字符的长度
        static int i = 0;
        if (rate <= MAX_RATE && rate >= 0)
        {
            printf("[%-100s][%3d%%][%c]\r", bar, rate, str[i % num]);//这里换成i是为了让旋转光标能够运作,不受进度条控制,可以让用户职别这个进度条究竟是卡住了还是仍在加载
            fflush(stdout);
            bar[rate] = STYLE;
            i++;
        }
        if (rate == MAX_RATE)//主要是用在下一次别的程序调用这个函数的时候,避免进度条数组中还有#
        {
            memset(bar, '\0', sizeof(bar));
        }//这样程序可以适用与不同的任务
    }
    void download_1(callback_t cb)//第一个下载任务,正常调用
    {
        int rate = 0;
        while (rate <= 100)
        {
            (*cb)(rate++);//回调函数
            Sleep(STIME);//单位为毫秒
        }
        printf("\n");
    }
    void download_2(callback_t cb)//第二个加载任务,模拟还在加载的情况,不是进度条程序卡住
    {
        int rate = 0;
        while (rate <= 100)
        {
            (*cb)(rate++);//回调函数
            if (rate == 50)
            {
                rate = 49;
            }
    
            Sleep(STIME);//单位为毫秒
        }
        printf("\n");
    
    }
    int main()
    {
        download_1(process_plus);
        download_2(process_plus);
        return 0;
    }

你可能感兴趣的:(操作系统学习笔记,linux,小程序,apache)