0

I'm working on a code and I'm using ncurses and stringstreams (C++).

I want to print (only) the number in red if it's negative and in green if it's positive.

By the structure of the program, I use a single stringstream for the entire output. So if I change the color with:

start_color();
init_pair(1, COLOR_RED, COLOR_BLACK);
init_pair(2, COLOR_GREEN, COLOR_BLACK);
attron(COLOR_PAIR(1));

It colors all the output (I just want the numbers to be colored). I've also tried with ANSI code, but it doesn't work with ncurses.

My code is something like this:

stringstream_var.clear();
stringstream_var.str(std::string());

if (num1 < 0){
  //I just want to print num1 in red
  stringstream_var << "Number 1: " << num1 << std::endl;
}else{
  //I just want to print num1 in green
  stringstream_var << "Number 1: " << num1 << std::endl;
}

How could I achive this?

Is it possible?

Gyntonic
  • 346
  • 2
  • 4
  • 14
  • So, If I well understand, you will then print stingstream_var in one shot to the terminal using ncurses primitive ? And you want that some substring of the big string to have different color ? – Gojita Mar 25 '19 at 13:15

1 Answers1

2

According to the official docs:

color pair 0 is special; it denotes "no color".

So you can create a helper function that takes a std::string a prints the text with a given color regarding the COLOR_PAIR value. Something like this:

#include <curses.h>

void print_with_color(const std::string& text, int color_pair) {
    attron(COLOR_PAIR(color_pair));
    printw(text.c_str());
}

void print_without_color(const std::string& text) {
    attron(COLOR_PAIR(0)); // No color
    printw(text.c_str());
}

int main(void) {
    initscr();
    start_color();

    init_pair(1, COLOR_BLACK, COLOR_RED);
    init_pair(2, COLOR_BLACK, COLOR_GREEN);

    print_without_color("Number 1: ");
    int number = std::rand();
    if (number) {
       print_with_color(std::to_string(number), 1);
    } else {
       print_with_color(std::to_string(number), 2);
    }
    refresh();
}

In any case, if you are going to use C++ streams, it may be better to look for a modern alternative. Check termcolor. You can do something like this:

if (number) {
   std::cout << "Number 1: " << termcolor::red << number << std::endl;
} else {
   std::cout << "Number 1: " << termcolor::green << number << std::endl;
}
mohabouje
  • 3,867
  • 2
  • 14
  • 28