Your C programs’ text output need not be so dull. Aside from adding wide characters, you can spice things up with color text. The terminal flavor is what determines the color palette. All you need to know are the secret codes that activate and deactivate the attributes.
The secret is ANSI, which uses escape sequences to encode various text attributes, among them colors. I wrote about ANSI in an blog post from 2020 regarding inverse text. The same type of sequences are used to generate color.
Don’t get too excited.
Be aware that not every terminal program recognizes ANSI sequences. Most do, so you should be in luck. If not, you can find alternative terminal apps available, some of which boast about their ANSI color capabilities.
ANSI defines eight color codes representing basic text colors: black, red, green, yellow, blue, magenta, cyan, and white. These can be foreground or background colors.
The escape sequence to generate colors starts with the escape character (get it?), followed by a left bracket, the color code value and a lowercase M. Here is the escape sequence as encoded in C:
\x1b[nnm
The nn is replaced by the color code values as listed in the following table.
Color | Foreground code | Background code | |
---|---|---|---|
0 | Black | 30 \x1b[30m |
40 \x1b[40m |
1 | Red | 31 \x1b[31m |
41 \x1b[41m |
2 | Green | 32 \x1b[32m |
42 \x1b[42m |
3 | Yellow | 33 \x1b[33m |
43 \x1b[43m |
4 | Blue | 34 \x1b[34m |
44 \x1b[44m |
5 | Magenta | 35 \x1b[35m |
45 \x1b[45m |
6 | Cyan | 36 \x1b[36m |
46 \x1b[46m |
7 | White | 37 \x1b[37m |
47 \x1b[47m |
The color codes can be combined in a single sequence if separated by a semicolon. So blue text on a red background has this sequence: \0x1b[34;41m
These codes can also be combined with other attributes, such as blinking and underline, if you really want to induce nausea in your users.
Another good code to know is \x1b[m
, which is the “normal” escape sequence. It disables all other attributes. I use this normal sequence after outputting any color text, which halts further color output. This trick avoids the color “bleed” that happens when you end a line of text.
To use these colors attributes in my code, I’ve wrote a series of defined constants to assist me. These values are declared as strings, as shown in this sample code:
2022_04_02-Lesson-a.c
#include <stdio.h> #define AC_BLACK "\x1b[30m" #define AC_RED "\x1b[31m" #define AC_GREEN "\x1b[32m" #define AC_YELLOW "\x1b[33m" #define AC_BLUE "\x1b[34m" #define AC_MAGENTA "\x1b[35m" #define AC_CYAN "\x1b[36m" #define AC_WHITE "\x1b[37m" #define AC_NORMAL "\x1b[m" int main() { printf("Color test:\n"); printf("%sThis is red text\n",AC_RED); printf("End test\n"); return(0); }
The code uses only the AC_RED
(ANSI Code red) literal to color all following text red. Figure 1 illustrates the output on my terminal, where the background color is preset to black and foreground to orange.
What you see in the output (Figure 1) is the color “bleed” to the following line. It looks worse when you set the background color. The solution is to output the AC_NORMAL
code when you want to reset all attributes to zero. Here is the updated Line 16:
printf("%sThis is red text%s\n",AC_RED,AC_NORMAL);
The updated code is found here at GitHub. The updated output is shown in Figure 2.
In next week’s Lesson, I explore the background colors, plus a few more tips for outputting color text to the terminal when coding in the C language.