The color output on the terminal does not reset

When writing a larger program, I came across a small problem with colored text. Here is a much simpler program that reproduces this problem.

#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 solves random line printing even after resetting the red colors. When launched in a new terminal, it always prints the expected result. If I did not run clear , there is no guarantee that the result will not be distorted, as in the second figure.

In the snapshots that I use xterm , although other terminals do the same.

What can I do to prevent this?

+5
source share
3 answers

As noted, this is a known behavior for some well-known terminals: when scrolling (or scrolling backward), the newly cleared area on the screen is filled with the current background color. The Linux console does this (with the exception of a crash several years ago noted in the terminal database ). xterm does this .

In ncurses, several related actions are combined together as a bce (background removal) function:

  • filling in newly cleared lines due to scroll
  • erasing the display, as well as deleting the part ending or beginning with the cursor.
  • erasing a line or erasing parts to or from the cursor to the end of the line
  • insert (space) at cursor position
  • character deletion

Normally, ncurses fills in the blanks (and this is only a problem when the terminal entry is poorly selected ) and you will not see this, but using simple escape sequences means that you will learn a little bit about the nuances of bce .

Terminal applications that use escape sequences directly to print color must reset the color before writing any other text that is not intended for coloring. Other applications (for example, editing lines in shells) should consider this rule when erasing text in a line

+3
source

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

The problem is probably due to the fact that puts adds a newline character. Change your code using printf .

 printf(COL_BG_RED); printf(str); puts(COL_RESET); puts(str); 
+3
source

When I run this locally, I also observe some odd behavior.

Using:

 #define COL_RESET "\0x1b[39;49m" // reset fore/back ground to normal #define COL_BG_RED "\033[41m" 

Conclusion:

enter image description here

Changing my #define to use octal rather than hexadecimal produces a different (expected) result.

Using:

#define COL_RESET "\033[39;49m"

Conclusion:

enter image description here

You can also see the creation of a macro to use printf with colors.

 #include <stdio.h> #define COL_RESET "\033[39;49m" #define COL_BG_RED "\033[41m" #define COL_BG_NORMAL "\033[49m" #define COLOR_NORMAL "\033[m" #define COLOR_RESET "\033[0m" #define COLOR_BLACK "\033[30m" #define COLOR_RED "\033[31m" #define COLOR_GREEN "\033[32m" #define COLOR_YELLOW "\033[33m" #define COLOR_BLUE "\033[34m" #define COLOR_MAGENTA "\033[35m" #define COLOR_CYAN "\033[36m" #define COLOR_WHITE "\033[37m" #define COLOR_PRINTF(colorCode,fmt,...) printf("%s" fmt "%s", colorCode, __VA_ARGS__, COL_RESET) char *str = "the quick brown fox jumped over the lazy dog"; int main(int argc, char *argv[]) { int i = 1; while (i) { COLOR_PRINTF(COLOR_GREEN, "%s\n", str); COLOR_PRINTF(COL_BG_RED, "%s\n", str); i--; } return 0; } 
0
source

All Articles