进度条小程序

小程序 0

在这里插入图片描述

文章目录

  • 铺垫
    • 回车换行
    • 缓冲区
      • 概述
      • 强制冲刷缓冲区
  • 简单实现倒计时功能
  • 进度条小程序
    • 版本一
      • 实例代码
      • 效果展示
      • 分析
    • 版本二

铺垫

回车换行

回车和换行是两个独立的动作

回车是将光标移动到当前行的最开始(最左侧)

换行是竖直向下平移一行

在C语言中,/n是同时进行了回车换行,/r实现了回车操作

缓冲区

概述

先来看一个小现象:

实例代码:

#include<stdio.h>                                                                                                                       #include<unistd.h>int main(){	printf("hello gwj,hello Linux.../n");    sleep(3);    return 0;}

在这里插入图片描述

运行mytest.exe执行程序,会输出hello gwj,hello Linux...,紧接着调用sleep函数,休眠三秒

如果将printf函数中/n删掉,会出现什么结果呢??

在这里插入图片描述
在这里插入图片描述

现象:先休眠三秒,在最后结束的狮虎打印出内容
这这种场景中,sleep函数和printf函数,哪一个先运行的呢??
答案是printf先运行,在休眠的这三秒时间里,printf已经执行完了,字符串被保存在缓冲区

缓冲区的概念需要在操作系统层面上理解,单纯在语言基础上是很难理解的

缓冲区是一个内存空间,当休眠的时候,字符串在缓冲区里,当程序结束return 0时,,强制冲刷缓冲区,再打印出字符串。

强制冲刷缓冲区

任何一个C语言程序都会默认打开三个流:

  • stdin:标准输入流
  • stdout:标准输出流
  • stderr比爱准错错误

可以通过fflush函数来刷新缓冲区

在这里插入图片描述

示例代码:

   #include<stdio.h>   #include<unistd.h>   int main()   {     printf("hello gwj,hello Linux...");     fflush(stdout);                                                                                                                            sleep(3);        return 0; }

在这里插入图片描述
现象:

在这里插入图片描述

简单实现倒计时功能

示例代码:

  1 #include<stdio.h>  2 #include<unistd.h>  3 int main()  4 {  5   int cnt=9;  6   while(cnt>=0)  7   {  8     printf("%d/r",cnt);  9     fflush(stdout);                                                                                                                      10     cnt--; 11     sleep(1); 12   } 13   return 0; 14 }

效果展示:

在这里插入图片描述

代码解读:
倒计时使用新数字去覆盖老数字,并且都出一同一位置,因此在printf函数里不能使用/n,使用换行会让新数字在老数字下面。

正确做法是在printf函数后面使用/r回车符号,每打印一个数字,让光标回到这一行最开始的位置,这样打印出来的新数字就会覆盖旧数字。

但是/r不会冲刷缓冲区,因此每打印完一个数字调用 fflush(stdout)来冲刷缓冲区。

进度条小程序

版本一

实例代码

Processbar.h文件:

#pragma once #include<stdio.h>void ProcBar();      
#include"Processbar.h"    #include<string.h>    #include<unistd.h>        #define Length 101    #define Style '#'        const char *lable="|/-//";        //version1:    void ProcBar()    {      char bar[Length];      memset(bar,'/0',sizeof(bar));      int len=strlen(lable);          int cnt=0;      while(cnt<=100)      {        printf("[%-100s][%3d%%][%c]/r",bar,cnt,lable[cnt%len]);                                                                                     fflush(stdout);        bar[cnt]=Style;        cnt++;        usleep(20000);      }      printf("/n");    }  

效果展示

在这里插入图片描述

分析

该进度条的原理是一次比一次多打印一点内容、

定义一个bar数组,通过循环,每次多打印一个字符,视觉上就会形成进度条是从右向左走

由于进度条每次打印是在同一行上,因此需要/r符号,让光标回到最开始的位置

版本二

Processbar.h文件:

#pragma once        #include <stdio.h>        typedef void(*callback_t)(double, double);    void ProcBar(double total, double current);                                                                                                 

Main.c文件:

void download(double filesize,callback_t cb)    {        double current = 0.0;            printf("download begin, current: %lf/n", current);        while(current <= filesize)        {            cb(filesize, current);            //从网络中获取数据                                                                                                                          usleep(100000);            current += bandwidth;        }        printf("/ndownload done, filesize: %lf/n",filesize);    }        int main()    {        download(100*1024*1024,ProcBar);        download(2*1024*1024,ProcBar);            return 0;    }    

Processbar.c文件:

#include"Processbar.h"    #include<string.h>    #include<unistd.h>        #define Length 101    #define Style '#'  //version 2                                                                   void ProcBar(double total, double current)                                    {                                                                                 char bar[Length];                                                             memset(bar, '/0', sizeof(bar));                                               int len = strlen(lable);                                                                                                                                    int cnt = 0;                                                                  double rate = (current*100.0)/total;                                          int loop_count = (int)rate;                                                   while(cnt <= loop_count)                                                      {                                                                                 bar[cnt++] = Style;                                                           usleep(20000);                                                                                                                          }                                                 printf("[%-100s][%.1lf%%][%c]/r", bar, rate, lable[cnt%len]);        fflush(stdout);    }  

效果展示:

在这里插入图片描述

在这里插入图片描述

也许您对下面的内容还感兴趣: