• 通过printf设置Linux终端输出的颜色和显示方式


    前言

         在Linux终端下调试程序时,有时需要输出大量信息。若能控制字体的颜色和显示方式,可使输出信息对比鲜明,便于调试时观察数据。

         终端的字符颜色由转义序列(Escape Sequence)控制,是文本模式下的系统显示功能,与具体语言无关。

         本文简要介绍C语言中通过printf改变终端输出的颜色和显示方式。文中涉及的代码运行环境如下:

     

     

     

    正文

         转义序列以控制字符'ESC'开头。该字符的ASCII码十进制表示为27,十六进制表示为0x1B,八进制表示为033。多数转义序列超过两个字符,故通常以'ESC'和左括号'['开头。该起始序列称为控制序列引导符(CSI,Control Sequence Intro),通常由'33['或'e['代替。

         通过转义序列设置终端显示属性时,可采用以下格式:

    33[ Param {;Param;...}m

    e[ Param {;Param;...}m

         其中,'33['或'e['引导转义序列,'m'表示设置属性并结束转义序列。Param为属性值,{...}表示可选(多个参数之间用分号隔开,与顺序无关)。例如,在Linux Shell中执行下述命令:

         即设置输出为红色字体(31),白色背景(47)。选项'-e'为echo命令激活特殊字符的解析器。

         注意,转义序列可被控制字符'CAN'(Cancel )和'SUB'(Substitute)中断。

         转义序列相关的常用参数如下(通过man console_codes命令可查看更多的参数描述):

    • 显示:0(默认)、1(粗体/高亮)、22(非粗体)、4(单条下划线)、24(无下划线)、5(闪烁)、25(无闪烁)、7(反显、翻转前景色和背景色)、27(无反显)
    • 颜色:0(黑)、1(红)、2(绿)、 3(黄)、4(蓝)、5(洋红)、6(青)、7(白)

         前景色为30+颜色值,如31表示前景色为红色;背景色为40+颜色值,如41表示背景色为红色。

        调色效果如下图所示:

     

         因此,通过转义序列设置终端显示属性时,常见格式为:

    33[显示方式;前景色;背景色m输出字符串33[0m

    e[显示方式;前景色;背景色m输出字符串33[0m

         其中 ,'33[0m'用于恢复默认的终端输出属性,否则会影响后续的输出。

         此外,还有一些ANSI控制码,如:nA (光标上移n行 )、nB(光标下移n行 )、nC(光标右移n行 )、nD (光标左移n行 )、2J(清屏)、K(清除从光标到行尾的内容)、s(保存光标位置)、u(恢复光标位置)、?25l(隐藏光标)、?25l(显示光标)。

         基于常用参数,可定义如下单一控制宏,用于printf系列语句:

     1 #define NONE                 "e[0m"
     2 #define BLACK                "e[0;30m"
     3 #define L_BLACK              "e[1;30m"
     4 #define RED                  "e[0;31m"
     5 #define L_RED                "e[1;31m"
     6 #define GREEN                "e[0;32m"
     7 #define L_GREEN              "e[1;32m"
     8 #define BROWN                "e[0;33m"
     9 #define YELLOW               "e[1;33m"
    10 #define BLUE                 "e[0;34m"
    11 #define L_BLUE               "e[1;34m"
    12 #define PURPLE               "e[0;35m"
    13 #define L_PURPLE             "e[1;35m"
    14 #define CYAN                 "e[0;36m"
    15 #define L_CYAN               "e[1;36m"
    16 #define GRAY                 "e[0;37m"
    17 #define WHITE                "e[1;37m"
    18 
    19 #define BOLD                 "e[1m"
    20 #define UNDERLINE            "e[4m"
    21 #define BLINK                "e[5m"
    22 #define REVERSE              "e[7m"
    23 #define HIDE                 "e[8m"
    24 #define CLEAR                "e[2J"
    25 #define CLRLINE              " e[K" //or "e[1K "

         编写测试代码验证转义序列控制的效果:

     1 int main(void)
     2 {
     3     printf("This is a character control test!
    " );
     4     sleep(3);
     5     printf("[%2u]" CLEAR "CLEAR
    " NONE, __LINE__);
     6 
     7     printf("[%2u]" BLACK "BLACK " L_BLACK "L_BLACK
    " NONE, __LINE__);
     8     printf("[%2u]" RED "RED " L_RED "L_RED
    " NONE, __LINE__);
     9     printf("[%2u]" GREEN "GREEN " L_GREEN "L_GREEN
    " NONE, __LINE__);
    10     printf("[%2u]" BROWN "BROWN " YELLOW "YELLOW
    " NONE, __LINE__);
    11     printf("[%2u]" BLUE "BLUE " L_BLUE "L_BLUE
    " NONE, __LINE__);
    12     printf("[%2u]" PURPLE "PURPLE " L_PURPLE "L_PURPLE
    " NONE, __LINE__);
    13     printf("[%2u]" CYAN "CYAN " L_CYAN "L_CYAN
    " NONE, __LINE__);
    14     printf("[%2u]" GRAY "GRAY " WHITE "WHITE
    " NONE, __LINE__);
    15 
    16     printf("[%2u]e[1;31;40m Red e[0m
    ",  __LINE__);
    17 
    18     printf("[%2u]" BOLD "BOLD
    " NONE, __LINE__);
    19     printf("[%2u]" UNDERLINE "UNDERLINE
    " NONE, __LINE__);
    20     printf("[%2u]" BLINK "BLINK
    " NONE, __LINE__);
    21     printf("[%2u]" REVERSE "REVERSE
    " NONE, __LINE__);
    22     printf("[%2u]" HIDE "HIDE
    " NONE, __LINE__);
    23 
    24     printf("Cursor test begins!
    " );
    25     printf("=======!
    " );
    26     sleep(10);
    27     printf("[%2u]" "e[2ACursor up 2 lines
    " NONE, __LINE__);
    28     sleep(10);
    29     printf("[%2u]" "e[2BCursor down 2 lines
    " NONE, __LINE__);
    30     sleep(5);
    31     printf("[%2u]" "e[?25lCursor hide
    " NONE, __LINE__);
    32     sleep(5);
    33     printf("[%2u]" "e[?25hCursor display
    " NONE, __LINE__);
    34     sleep(5);
    35 
    36     printf("Test ends!
    " );
    37     sleep(3);
    38     printf("[%2u]" "e[2ACursor up 2 lines
    " NONE, __LINE__);
    39     sleep(5);
    40     printf("[%2u]" "e[KClear from cursor downward
    " NONE, __LINE__);
    41 
    42     return 0 ;
    43 }

         执行结果截图如下:

     

         因截图所限,未能展示闪烁和光标移动等效果。

         注意,Linux终端下可正常显示彩色字符。但若通过SecureCRT等Windows工具SSH登录Linux主机,则需对工具做些设置。

         以SecureCRT 6.6为例,在Options->Session Options->Terminal->Emulation页的Terminal类型中选择ANSI或Linux或Xterm,并勾选ANSI Color。

     

         然后,在Appearance页中选择颜色方案为Windows或Traditional。为突出测试代码中的输出颜色,此处选择Windows方案(需要在Emulation页勾选Use color scheme):

     

     

     

  • 相关阅读:
    day13_迭代器,生成器
    作业礼包
    day12_装饰器进阶
    装饰器作业
    day11_装饰器
    函数作业
    day10-函数进阶
    数据类型-习题解答
    day09_函数
    PHP 完美分页
  • 原文地址:https://www.cnblogs.com/clover-toeic/p/4031618.html
Copyright © 2020-2023  润新知