Colour output of program run under BASH [closed]

2020-02-28 04:27发布

问题:

Closed. This question needs to be more focused. It is not currently accepting answers.

Want to improve this question? Update the question so it focuses on one problem only by editing this post.

Closed 12 months ago.

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.

回答1:

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";
}


回答2:

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;
}


回答3:

You might want to look at VT100 control codes.



回答4:

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



回答5:

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;
}