Linux小程序:进度条

目录

一、换行与回车

二、缓冲区

三、倒计时代码

四、进度条实现


实现进度条程序,首先需要两个预备知识:

1.换行与回车

2.缓存区

一、换行与回车

我们通常使用\n作为换行符,但实际上\n是换行+回车两种效果的结合,因此我们需要区分一下换行与回车的区别:

换行是从上一行的第n个位置跳转到下一行的第n个位置;回车则是从某一行的第n个位置跳转到该行的第一个位置

\r表示回车,\r\n表示回车+换行(只有\n和\r一起使用时,\n才表示换行),\n表示回车+换行

二、缓冲区

先对比两段代码,唯一的区别就是printf函数输出时有没有加上\n

运行时,代码1会先输出内容,再等待3秒;代码2会先等待3秒,再输出内容

由此引入问题:代码2先等待3秒,但是程序运行时一定是按顺序执行代码,也就是说是printf函数先执行,那么再等待的这3秒内,printf函数输出的数据在哪里呢?

答案是:在缓冲区,printf输出的数据会被拷贝到缓冲区,在程序运行结束的时候会冲刷缓冲区,此时printf输出的数据才会显示出来

cpp 复制代码
//第一段代码
#include <stdio.h>
#include <unistd.h>
int main()
{
   printf("hello makefile\n");
   sleep(3);                                                                                                       
   return 0;
}

//第二段代码
#include <stdio.h>
#include <unistd.h>
int main()
{
   printf("hello makefile");
   sleep(3);                                                                                                       
   return 0;
}

缓冲区的三种冲刷方式:

(1)\n冲刷

printf输出时加上\n,printf输出的数据被拷贝到缓冲区,\n会自动冲刷缓冲区

(2)fflush强制冲刷

我们可以调用fflush函数强制冲刷缓冲区,包含在头文件<unistd.h>

(3)程序运行结束冲刷

程序运行结束时,也会自动冲刷缓冲区

三、倒计时代码

根据上面的理解,我们可以实现一个简单的倒计时代码

C语言在输出时会默认打开3个标准输入输出流,分别为stdin、stdout、stderr,其中stdin为键盘输入,stdout和stderr都是显示器输出

cpp 复制代码
#include <stdio.h>
#include <unistd.h>
int main()
{
   int cnt=9;
   while(cnt>=0)
   {                                                                             
     printf("倒计时:%d\r",cnt);                     
     fflush(stdout);              
     sleep(1);                                                                                                     
     cnt--;                                     
   }                                  
   printf("\n");//最后一行\n的作用是防止程序最后的输出倒计时:0 被命令行提示符覆盖
                //因为\r回车,光标回到了倒计时:0的前面,此时再输出命令行提示符一定会覆盖倒计时:0
                //而使用\n换行后,缓冲区的光标就会跳到 倒计时:0 的下一行,此时输出命令行提示符就不会覆盖倒计时:0
   return 0;                             
}      

如果cnt初始值为10,则始终有一个0无法被覆盖,此时我们需要将%d改为%2d,使得输出字段的最小宽度为2,小于2则在左侧用空格补齐,这样就能覆盖掉0了

cpp 复制代码
#include <stdio.h>
#include <unistd.h>
int main()
{
   int cnt=10;
   while(cnt>=0)
   {                                                                             
     printf("倒计时:%2d\r",cnt);                     
     fflush(stdout);              
     sleep(1);                                                                                                     
     cnt--;                                     
   }                                  
   printf("\n");
   return 0;                             
}      

四、进度条实现

cpp 复制代码
//progress_bar.h
void progress_bar();

//progress_bar.c
#include <stdio.h>
#include "progress_bar.h"
#include <memory.h>
#include <unistd.h>
#define out '#'
void progress_bar()
{
    char rotate[4] = {'|', '/', '\\', '-'};
    char arr[101];
    memset(arr, '\0', 101);
    int cnt = 0;
    while (cnt < 100)
    {
        arr[cnt] = out;
        printf("[%-100s][%d%%][%c]\r", arr, cnt + 1, rotate[cnt % 4]);
        fflush(stdout);
        usleep(20000); // usleep,单位为微秒
        cnt++;
    }
    printf("\n");
}

//main.c
#include <stdio.h>
#include "progress_bar.h"
int main()
{
    progress_bar();
    return 0;
}
相关推荐
诚信爱国敬业友善18 分钟前
GUI编程(window系统→Linux系统)
linux·python·gui
sekaii19 分钟前
ReDistribution plan细节
linux·服务器·数据库
YH_DevJourney1 小时前
Linux-C/C++《C/8、系统信息与系统资源》
linux·c语言·c++
威哥爱编程2 小时前
Linux驱动开发13个实用案例
linux
去看日出2 小时前
Linux(centos)系统安装部署MySQL8.0数据库(GLIBC版本)
linux·数据库·centos
qq_448941082 小时前
10、k8s对外服务之ingress
linux·容器·kubernetes
D-river3 小时前
【如何基于Debian构建Kali Linux】
linux·网络·安全·网络安全
年轮不改3 小时前
ARM-Linux 基础项目篇——简单的视频监控
linux·arm开发
程序员JerrySUN4 小时前
树莓派 4B:AI 物联网完整部署方案
linux·人工智能·嵌入式硬件·物联网·分类·数据挖掘
柳鲲鹏4 小时前
Ubuntu编译ZLMediaKit
linux·运维·ubuntu