Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Colored terminal output does not reset

While writing a larger program I stumbled upon a small problem with colored text output. Here's a much simpler program that reproduces this issue.

#include <stdio.h>

#define COL_RESET "\033[0m"
#define COL_BG_RED  "\x1B[41m"

char *str = "the quick brown fox jumped over the lazy dog";

int main(int argc, char *argv[])
{
    int i = 10;
    while (i) {
        puts(COL_BG_RED);
        puts(str);
        puts(COL_RESET);
        puts(str);
        i--;
    }
    return 0;
}

Now this is what I get when I run the program:

First time - expected result

first time

Second time

enter image description here

As you can tell, the program decides to randomly print lines even after resetting the colors in red. When started in a fresh terminal it always prints the expected result. Unless I run clear, there is no guarantee the output won't be mangled like in the second picture.

In the pictures I'm using xterm, although other terminals do the same thing.

What can I do to prevent this?

like image 988
Alexguitar Avatar asked May 05 '15 17:05

Alexguitar


2 Answers

As commented, this is known behavior for some well-known terminals: when scrolling (or reverse-scrolling), the newly cleared area on the screen is filled with the current background color. Linux console does this (except for a glitch some years ago, noted in the terminal database). xterm does it.

In ncurses, several related behaviors are lumped together as the bce (background color erase) feature:

  • filling newly-cleared rows due to scrolling
  • erasing the display, as well as erasing the part ending with or beginning with the cursor.
  • erasing a line, or erasing the part up to, or from the cursor to the end of the line
  • inserting (a blank) at the cursor position
  • deleting a character

Normally ncurses fills in the blanks (and it is only a problem when the terminal entry is poorly chosen), and you would not see this. But using plain escape sequences means that you get to explore the nuances of bce a little.

Terminal applications which use escape sequences directly for printing color should reset the color before writing any other text which is not intended to be colored. Other applications (such as line-editing in shells) have to keep this rule in mind when erasing text within the line

like image 174
Thomas Dickey Avatar answered Sep 30 '22 07:09

Thomas Dickey


It seems that the issue occurs when the terminal starts scrolling.

The problem is probably caused by the fact that puts appends a new-line character. Modify your code by using printf.

printf(COL_BG_RED);
printf(str);
puts(COL_RESET);
puts(str);
like image 22
huysentruitw Avatar answered Sep 30 '22 09:09

huysentruitw