10

I need to be able to be able to make some text on terminal more noticeable, and what I thought was to make the text colored. Either the actual text, or the space in each letter's rectangle-thingy (think vi's cursor). The only two extra specs that I think are important for my application are : the program should be distro-independent (a certainty is that the code will only be run under BASH), and it shouldn't output extra characters when writing to a file (either from the actual code, or when piping the output)

I searched the web for some info, but I could only find info for the deprecated cstdlib (stdlib.h), and I need (actually, it's more of a "want") to do it using the functionality of iostream.

Patrunjel
  • 129
  • 1
  • 9

5 Answers5

14

Most terminals respect the ASCII color sequences. They work by outputting ESC, followed by [, then a semicolon-separated list of color values, then m. These are common values:

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

So outputting "\033[31;47m" should make the terminal front (text) color red and the background color white.

You can wrap it nicely in a C++ form:

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";
}
ruakh
  • 175,680
  • 26
  • 273
  • 307
orlp
  • 112,504
  • 36
  • 218
  • 315
4

Here's a version of the code above from @nightcracker, using stringstream instead of itoa. (This runs using clang++, 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;
}
Patrick Sanan
  • 2,375
  • 1
  • 23
  • 25
2

You might want to look at VT100 control codes.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

You can use libcolor from github (https://github.com/Spezialcoder/libcolor)

#include "libcolor/libcolor.h"
#include <iostream>
using namespace std; 
int main()
{
     cout << font_color::green << "Hello World" << endl;
}
0

You can also make custom function like:

void textcolor(int color)
{
    std::cout<<"\033]"<<color;
}

For more info read http://en.wikipedia.org/wiki/ANSI_escape_code

noisy cat
  • 2,865
  • 5
  • 33
  • 51