LINUX 实现终端动态进度条记录

1、转义字符 \r \n 的区别

\r 代表回车,他会清空光标所在行设为数据并将该行的内容清除。

\n 代表换行,将光标移动到下一行。

2、ffush的作用

fflush刷新缓存,fflash(stdout),就是将标准输出的缓存输出并清空。

我们知道LINUX中stdout是行缓冲,啥意思,遇到换行符\n才输出缓存内容

3、动态进度条实现原理

通过一个buff 或者直接通过 printf 输出ESC 控制符设置 ,设置前景或者背景色,表示进度。

在开始输出前输出\r 将光标移动至行首并清空行。

输出完毕,调用 fflash(stdout) ,清空缓存,防止下次还输出上次的值。

3、实现

颜色控制头文件

c 复制代码
#ifndef __COLOR_H
#define __COLOR_H

//进度条使用背景色
#define COLOR_RED       "41"
#define COLOR_GREE      "42"
#define COLOR_YELLOW    "43"
#define COLOR_WHITE     "47"
//数字使用前景色
#define COLOR_RED_NUM       "31"   
#define COLOR_GREE_NUM      "32"
#define COLOR_YELLOW_NUM    "33"   
#define COLOR_WHITE_NUM     "37"   

#endif/*__COLOR_H*/

字符控制头文件

c 复制代码
#ifndef __SHOW_TYPES_H
#define __SHOW_TYPES_H




#endif/*__SHOW_TYPES_H*/

总控制头文件

c 复制代码
#ifndef __CONTROL_H
#define __CONTROL_H
//颜色头文件
#include "color.h"
#include "show_types.h"

//进度条宽度
#define BAR_WIDTH  50
#define ESC_PREFIXES    "\033["
#define ESC_SUFFIX      "m"
#define ESC_NULL        "\033[0m"
//==================================
//是否用字符表示进度条
#define USE_CHAR    1
#if USE_CHAR
//进度条 已完成部分字符
#define CONTROL_HEAD_CHAR "#"

//进度条未完成部分 字符
#define CONTROL_TAIL_CHAR " "
#endif /*#if USE_CHAR*/
//==================================

//进度条 已完成部分 颜色
#define CONTROL_HEAD_COLOR        COLOR_GREE
//进度条未完成部分 颜色
#define CONTROL_TAIL_COLOR        COLOR_WHITE


//==================================
//是否显示进度数字
#define PROGRESS__NUM     1

#if PROGRESS__NUM

#define PROGRESS__NUM_COLOR   COLOR_RED_NUM //color

#endif/*#if CONTROL_NUM*/
//==================================

源代码和测试函数

c 复制代码
#include <strings.h>
#include "control.h"
#include <unistd.h>
void show_bar(int progress,int total)
{
    char head_buff[64]={0}; //用来拼接控制字符串
    char tail_buff[64]={0}; //用来拼接控制字符串
    char num_buff[64]={0};
    int progress_num = (progress*100)/total; 
    bzero(head_buff,sizeof(head_buff));
    bzero(tail_buff,sizeof(head_buff));

    strncat(head_buff,ESC_PREFIXES,sizeof(ESC_PREFIXES));
    strncat(tail_buff,ESC_PREFIXES,sizeof(ESC_PREFIXES));
    strncat(head_buff,CONTROL_HEAD_COLOR,sizeof(CONTROL_HEAD_COLOR));
    strncat(tail_buff,CONTROL_TAIL_COLOR,sizeof(CONTROL_TAIL_COLOR));
    strncat(head_buff,ESC_SUFFIX,sizeof(ESC_SUFFIX));
    strncat(tail_buff,ESC_SUFFIX,sizeof(ESC_SUFFIX));
    #if USE_CHAR
    strncat(head_buff,CONTROL_HEAD_CHAR,sizeof(CONTROL_HEAD_CHAR));
    strncat(tail_buff,CONTROL_TAIL_CHAR,sizeof(CONTROL_TAIL_CHAR));
    #else
    strncat(head_buff," ",sizeof(" ")); 
    strncat(tail_buff," ",sizeof(" "));
    #endif
    strncat(head_buff,ESC_NULL,sizeof(ESC_NULL));
    strncat(tail_buff,ESC_NULL,sizeof(ESC_NULL));
    #if PROGRESS__NUM
    bzero(num_buff,sizeof(head_buff));
    strncat(num_buff,ESC_PREFIXES,sizeof(ESC_PREFIXES));
    strncat(num_buff,PROGRESS__NUM_COLOR,sizeof(PROGRESS__NUM_COLOR));
    strncat(num_buff,ESC_SUFFIX,sizeof(ESC_SUFFIX)); 
    #endif

    //start show
    int i;
    printf("\r[");
    for(i=0;i<BAR_WIDTH;i++)
    {
        if(i<(progress_num/(100/BAR_WIDTH)))
        {
            printf("%s",head_buff);
        }
        else
        {
            printf("%s",tail_buff);
        }
    }
    printf("]  ");
    #if PROGRESS__NUM
    printf("%s",num_buff);
    printf("%d %%",progress_num);
    printf("%s",ESC_NULL);
    #endif
    fflush(stdout);
}

int main()
{
    int i =0;
    for(i=1;i<=130;i++)
    {
        show_bar(i,130);
        usleep(5000);
    }
    printf("\n Download complete\n");
}

问题记录

1、终端作为一个进程,它的stdin\stdout\stderr缓存是怎样的?为什么终端中开启进程,进程的stdin\stdout\stderr 是直接在终端输出?这其中有什么关系?

相关推荐
wanhengidc10 分钟前
云手机 高振畅玩不踩坑
运维·服务器·安全·web安全·智能手机
有谁看见我的剑了?17 分钟前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
JoyCong199828 分钟前
ToDesk远程屏幕墙技术白皮书:如何重塑全局运维视界
运维·电脑·远程工作
偶尔上线经常挺尸1 小时前
《100个“反常识”经验15:Nginx 502排查:从应用到内核》
运维·nginx·性能调优·反向代理·502错误·http排错
yc_12242 小时前
用 Visual Studio 远程调试 Linux:从零到流畅的完整指南
linux·ide·visual studio
思茂信息2 小时前
CST软件如何进行参数化扫描?
运维·开发语言·javascript·windows·ecmascript·软件工程·软件需求
计算机安禾2 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
下一页盛夏花开2 小时前
ubuntu 20中安装QT以后出现红色空心断点
linux·运维·ubuntu
金色光环3 小时前
FreeModbus释放底层的 TCP 监听端口
服务器·网络·tcp/ip
sanshanjianke3 小时前
Thunderobot 911ME 笔记本 Linux 风扇控制研究
linux