2012-03-30 46 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; 
}