zoukankan      html  css  js  c++  java
  • Linux终端彩色打印+终端进度条【转】

    转自:https://my.oschina.net/jcseg/blog/178047

    开发的一个应用程序选择了终端界面, 为了使软件稍微好看些, 研究下Linux终端的彩色打印, 并且基于这个彩色打印实现了几种进度条, 在此总结下: (更多的是觉得这个东西挺好玩的... )

    一. Linux终端色彩打印:

    1. 属性介绍: 

    (1). 来自网络的ANSI属性控制码: 

    033[0m                 关闭所有属性
    033[1m                 设置高亮度
    033[4m                 下划线
    033[5m                 闪烁
    033[7m                 反显
    033[8m                 消隐
    033[30m -- 33[37m    设置前景色
    033[40m -- 33[47m    设置背景色
    033[nA                 光标上移n行
    033[nB                 光标下移n行
    033[nC                 光标右移n列
    033[nD                 光标左移n列
    033[y;H                设置光标位置
    033[2J                 清屏
    033[K                  清除从光标到行尾的内容
    033[s                  保存光标位置
    033[u                  恢复光标位置
    033[?25l               隐藏光标
    033[?25h               显示光标

    (2). 文字背景色彩数字: (颜色范围:40 - 49)

    40:    黑色
    41:    深红色
    42:    绿色
    43:    黄色
    44:    蓝色
    45:    紫色
    46:    深绿色
    47:    白色

    (3). 文字前景色数字: (颜色范围: 30 - 39)

    30:    黑色
    31:    红色
    32:    绿色
    33:    黄色
    34:    蓝色
    35:    紫色
    36:    深绿色
    37:    白色

    2. 使用例子:

    Linux终端会解析这些控制码, 并且依据控制码来设置终端的绘制属性, 所以, 只要输出流中包含ANSI控制码就可以工作, 这里使用linux的echo命令来演示:  (你可以使用任何你熟悉的语言来代替...)

    (1). 字体红色输出:   

    查看上面的ANSI控制码可以知道: 33[30m -- 33[37m是控制前景色, 并且红色使用31表示, 即: 红色ANSI控制码为:  33[31m

    echo -e "33[31m红色字体33[0m"     #需要加上-e参数

    从33[31m处开始使用"红色"作为字体的前景色, 后面全部的绘制都使用红色, 直到遇到属性关闭控制码. 所以: 后面使用33[0m来关闭属性, 要不然终端后面的输入的文字将全部是红色的. 效果图:

    (2). 使用多个控制码产生叠加效果:  红色+高亮

    echo -e "33[31m33[1m红色+高亮33[0m"   #高亮控制码为: 33[1m

    效果:

    (3). 红底+白字+高亮+下划线:

    echo -e "33[41m33[37m33[1m33[4m红底+白字+高亮+下划线33[0m"

    效果:

    多个控制码可以一起使用, 从而看到叠加的效果, 控制码之间的顺序无所谓, 例如: 上面的高亮和下划线.  其他的控制码就可以自己试试了.

    二. Linux终端进度条的实现:

    了解了上面的Linux终端彩色打印, 就可以开始做出漂亮的终端进度条了.

     1. 利用 backspace符来制作进度条:

    (1). 一个php例子如下:  (注意, php要使用printf, echo没用的)

    <?php
    for ($i = 0; $i <= 50; $i++) {
      printf("mprogress: %d%% %s
    ", $i * 2, str_repeat('#',$i) );
      usleep(1000 * 100);
    }
    echo "
    ", "Done.
    ";
    ?>

    运行效果如下:

    (2). 加上色彩:

    (3). 进一步美化, 使用背景并且使用空格代替'#'字符:

    <?php
    for ($i = 0; $i <= 50; $i++) {
      printf("mprogress: 33[41m33[1m %d%% %s
    33[0m", $i * 2, str_repeat(' ',$i) );
      usleep(1000 * 100);
    }
    echo "
    ", "Done.
    ";
    ?>

    效果:

    哈, 效果还不错呢.

    (4). 终极美化, 将光标隐藏:

    这个只要在里面加上隐藏光标的ANSI控制码就ok了, 不过记得要在后面将光标回复显示, 要不然后面终端就看不到光标了:

    <?php
    for ($i = 0; $i <= 50; $i++) {
      printf("33[?25lmprogress: 33[41m33[1m %d%% %s
    33[0m", $i * 2, str_repeat(' ',$i) );
      usleep(1000 * 100);
    }
    printf("
    Done.
    33[?25h");
    ?>

    效果:

    到此Linux终端进度条制作完毕.

    三. 一个C的进度条封装: 

    1. progress.h头文件: 

    /**
     * linux terminal progress bar (no thread safe).
     * 	@package progress.h.
     *
     * @author chenxin <chenxin619315@gmail.com>
     */
    #ifndef progress_h
    #define progress_h
    
    #include <stdio.h>
    
    typedef struct {
        char chr;		/*tip char*/
        char *title;	/*tip string*/
        int style;		/*progress style*/
        int max;		/*maximum value*/
        float offset;
        char *pro;
    } progress_t;
    
    #define PROGRESS_NUM_STYLE 0
    #define PROGRESS_CHR_STYLE 1
    #define PROGRESS_BGC_STYLE 2
    
    extern void progress_init(progress_t *, char *, int, int);
    
    extern void progress_show(progress_t *, float);
    
    extern void progress_destroy(progress_t *);
    
    #endif	/*ifndef*/

    2. progress.c 源程序:

    /**
     * linux terminal progress bar (no thread safe).
     * 	@package progress.c
     *
     * @author chenxin <chenxin619315@gmail.com>
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    #include "progress.h"
    
    /**
     * initialize the progress bar.
     * @max = 0
     * @val = 0
     *
     * @param	style
     * @param	tip words.
     */
    extern void progress_init(
    	progress_t *bar, char *title, int max, int style)
    {
        bar->chr = '#';
        bar->title = title;
        bar->style = style;
        bar->max = max;
        bar->offset = 100 / (float)max;
        bar->pro = (char *) malloc(max+1);
        if ( style == PROGRESS_BGC_STYLE )
    	memset(bar->pro, 0x00, max+1);
        else {
    	memset(bar->pro, 32, max);
    	memset(bar->pro+max, 0x00, 1);
        }
    }
    
    extern void progress_show( progress_t *bar, float bit )
    {
        int val = (int)(bit * bar->max);
        switch ( bar->style ) 
        {
        case PROGRESS_NUM_STYLE:
    	printf("33[?25l33[31m33[1m%s%d%%33[?25h33[0m
    ",
    		bar->title, (int)(bar->offset * val));
    	fflush(stdout);
    	break;
        case PROGRESS_CHR_STYLE:
    	memset(bar->pro, '#', val);
    	printf("33[?25l33[31m33[1m%s[%-s] %d%%33[?25h33[0m
    ", 
    		bar->title, bar->pro, (int)(bar->offset * val));
    	fflush(stdout);
    	break;
        case PROGRESS_BGC_STYLE:
    	memset(bar->pro, 32, val);
    	printf("33[?25l33[31m33[1m%s33[41m %d%% %s33[?25h33[0m
    ", 
    		bar->title, (int)(bar->offset * val), bar->pro);
    	fflush(stdout);
    	break;
        }
    }
    
    //destroy the the progress bar.
    extern void progress_destroy(progress_t *bar)
    {
        free(bar->pro);
    }

    3. tst-pro.c测试程序:

    /**
     * program bar test program.
     *
     * @author chenxin <chenxin619315@gmail.com>
     */
    #include "progress.h"
    #include <unistd.h>
    
    int main(int argc, char *argv[] )
    {
        progress_t bar;
        //progress_init(&bar, "", 50, PROGRESS_NUM_STYLE);
        progress_init(&bar, "", 50, PROGRESS_CHR_STYLE);
        //progress_init(&bar, "", 50, PROGRESS_BGC_STYLE);
    
        int i;
        for ( i = 0; i <= 50; i++ ) {
    	progress_show(&bar, i/50.0f);
    	sleep(1);
        }
        printf("
    +-Done
    ");
    
        progress_destroy(&bar);
    
        return 0;
    }

    4. 测试效果: 

    (1). PROGRESS_NUM_STYLE效果:

    (2). PROGRESS_CHR_STYLE效果:

    (3). PROGRESS_BGC_STYLE效果:

    完毕. 代码托管到: http://git.oschina.net/lionsoul/ltpro

  • 相关阅读:
    js node 节点 原生遍历 createNodeIterator
    nodejs fs copy本地文件src dst
    axios 请求常用组件,及其错误
    【IntelliJ IDEA学习之三】IntelliJ IDEA常用快捷键
    【IntelliJ IDEA学习之二】IntelliJ IDEA常用配置
    【IntelliJ IDEA学习之一】IntelliJ IDEA安装激活、VM参数
    【python学习案例】python判断自身是否正在运行
    【Linux脚本学习案例】shell脚本多通道并发执行存储过程
    【Activiti学习之四】Activiti API(三)
    【Activiti学习之三】Activiti API(二)
  • 原文地址:https://www.cnblogs.com/sky-heaven/p/7137838.html
Copyright © 2011-2022 走看看