2012-03-30 10 views
10

Necesito poder hacer algo de texto en el terminal más notable, y lo que pensé fue hacer que el texto se coloreara. O bien el texto real, o el espacio en el rectángulo de cada letra (piensa en el cursor de vi). Las únicas dos especificaciones adicionales que creo que son importantes para mi aplicación son: el programa debe ser independiente de la distribución (una certeza es que el código solo se ejecutará bajo BASH), y no debe generar caracteres adicionales al escribir en un archivo (ya sea desde el código real, o al canalizar la salida)Salida de color del programa ejecutado bajo BASH

Busqué información en la web, pero solo pude encontrar información para el cstdlib en desuso (stdlib.h) y necesito (en realidad, es más de un "querer") para hacerlo usando la funcionalidad de iostream.

Respuesta

12

La mayoría de los terminales respetan las secuencias de color ASCII. Funcionan dando como resultado ESC, seguido por [, luego una lista de valores de color separados por punto y coma, luego m. Estos son los valores comunes:

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 

Así salida "\033[31;47m" debe hacer frente el terminal (texto) de color rojo y el color de fondo blanco.

Puede envolverlo bien en un C++ formulario:

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

No se olvide del terminador '' m'' de la secuencia, como ' "\ 033] 31; 47m" '. –

+0

@JoachimPileborg: arreglado. – orlp

4

Aquí hay una versión de la codifique arriba desde @nightcracker, usando stringstream en lugar de itoa. (Esto se ejecuta utilizando sonido metálico ++, C++ 11, OS X 10.7, iTerm2, fiesta)

#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; 
} 
Cuestiones relacionadas