2012-03-30 51 views
10

我需要能够使一些终端上的文本更明显,并且我认为是让文本变成彩色。无论是实际文本,还是每个字母的矩形空间(想想vi的光标)。我认为对于我的应用程序来说,唯一的两个额外规格是:程序应该独立于发行版(确定性代码只能在BASH下运行),并且在写入文件时不应该输出额外的字符(无论是从实际的代码,或管道输出)在BASH下运行的程序的颜色输出

我在网上搜索了一些信息,但我只能找到不赞成的cstdlib(stdlib.h)的信息,我需要(实际上,它是更多一个“想要”)使用iostream的功能来做到这一点。

回答

12

大多数终端都遵守ASCII颜色序列。他们的工作方式是输出ESC,然后输入[,然后输入颜色值的分号分隔列表,然后输入m。这些都是常见的值:

Special 
0 Reset all attributes 
1 Bright 
2 Dim 
4 Underscore 
5 Blink 
7 Reverse 
8 Hidden 

Foreground colors 
30 Black 
31 Red 
32 Green 
33 Yellow 
34 Blue 
35 Magenta 
36 Cyan 
37 White 

Background colors 
40 Black 
41 Red 
42 Green 
43 Yellow 
44 Blue 
45 Magenta 
46 Cyan 
47 White 

所以输出"\033[31;47m"应该使终端正面(文字)色和红色的背景色为白色。

您可以在C++的形式很好地把它包:

enum Color { 
    NONE = 0, 
    BLACK, RED, GREEN, 
    YELLOW, BLUE, MAGENTA, 
    CYAN, WHITE 
} 

std::string set_color(Color foreground = 0, Color background = 0) { 
    char num_s[3]; 
    std::string s = "\033["; 

    if (!foreground && ! background) s += "0"; // reset colors if no params 

    if (foreground) { 
     itoa(29 + foreground, num_s, 10); 
     s += num_s; 

     if (background) s += ";"; 
    } 

    if (background) { 
     itoa(39 + background, num_s, 10); 
     s += num_s; 
    } 

    return s + "m"; 
} 
+1

不要忘记序列,如'的端接''m'' “\ 033] 31;47米” '。 – 2012-03-30 13:07:34

+0

@JoachimPileborg:固定。 – orlp 2012-03-30 13:08:38

4

这里的一个版本以上代码来自@nightcracker,使用stringstream而不是itoa。 (这将运行使用铛++,C++ 11,OS X 10.7,iTerm2时,bash)

#include <iostream> 
#include <string> 
#include <sstream> 

enum Color 
{ 
    NONE = 0, 
    BLACK, RED, GREEN, 
    YELLOW, BLUE, MAGENTA, 
    CYAN, WHITE 
}; 

static std::string set_color(Color foreground = NONE, Color background = NONE) 
{ 
    std::stringstream s; 
    s << "\033["; 
    if (!foreground && ! background){ 
     s << "0"; // reset colors if no params 
    } 
    if (foreground) { 
     s << 29 + foreground; 
     if (background) s << ";"; 
    } 
    if (background) { 
     s << 39 + background; 
    } 
    s << "m"; 
    return s.str(); 
} 

int main(int agrc, char* argv[]) 
{ 
    std::cout << "These words should be colored [ " << 
     set_color(RED) << "red " << 
     set_color(GREEN) << "green " << 
     set_color(BLUE) << "blue" << 
     set_color() << " ]" << 
     std::endl; 
    return EXIT_SUCCESS; 
}