162

I am making a simple application which requires colored output. How can I make my output colored like emacs and bash do?

I don't care about Windows, as my application is only for UNIX systems.

user5534993
  • 518
  • 2
  • 17

8 Answers8

355

All modern terminal emulators use ANSI escape codes to show colours and other things.
Don't bother with libraries, the code is really simple.

More info is here.

Example in C:

#include <stdio.h>

#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_BLUE    "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN    "\x1b[36m"
#define ANSI_COLOR_RESET   "\x1b[0m"

int main (int argc, char const *argv[]) {

  printf(ANSI_COLOR_RED     "This text is RED!"     ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_GREEN   "This text is GREEN!"   ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_YELLOW  "This text is YELLOW!"  ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_BLUE    "This text is BLUE!"    ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_MAGENTA "This text is MAGENTA!" ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_CYAN    "This text is CYAN!"    ANSI_COLOR_RESET "\n");

  return 0;
}
Andrejs Cainikovs
  • 27,428
  • 2
  • 75
  • 95
  • 2
    But I suppose I can run bash in a terminal emulation that does not support ANSI escape seqs. – ShinTakezou Jul 10 '10 at 14:55
  • @ShinTakezou: Yes.. In this case all the ANSI escape codes will be ignored, and you will have no options to make the fancy output. – Andrejs Cainikovs Jul 10 '10 at 15:07
  • Will this work in xterm? What happens if I change my terminal settings and run this code? Seems pretty silly to do your own terminal escaping when you dont have to. Anyway, might well be good enough for OP. –  Jul 10 '10 at 17:43
  • @Andrejs: I know how it works. My claim is that this approach is not a portable enough method and very restrictive (work only with ANSI compatible terminals). Just because the code is 'simple' does not mean you have to use it. Add a few more terminals to support and the code will become complicated and hard to maintain. It is best to use an already available library. In fact even with ANSI, the CSI might be different between terminals, so it might not even work will all ANSI compatible terminals (not so sure about this though). –  Jul 10 '10 at 21:23
  • @Moron: I thought real CSI (0x9b) is not recognized by some terminal emulators, but any sane mostly ANSI/ECMA-48 compatible terminal emulator recognized 7-bit CSI (ESC [)? – ninjalj Jul 12 '10 at 20:20
  • @ninjalj: Probably, but like I said, I am not very sure. –  Jul 12 '10 at 20:54
  • 10
    Especially loved the "don't bother with libraries"! ANSI codes even work in the Windows command prompt. – SzG Dec 21 '15 at 22:13
  • @SzG, I tried it with the Windows 11 command prompt but it doesn't work, it just prints the escape sequence. It only works in the command prompt embedded in VSCode. – FLAK-ZOSO Mar 03 '22 at 14:14
  • @FLAK-ZOSO I tried it with cmd in VSCode and it still doesn't work – Yugoslav Empire May 28 '22 at 11:23
  • @YugoslavEmpire, try with Windows Terminal, the new terminal since Windows 11, it works perfectly. Read this: https://superuser.com/questions/1713502/windows-11-command-prompt-printing-characters-instead-of-coloured-text – FLAK-ZOSO May 28 '22 at 12:48
15

Dealing with colour sequences can get messy and different systems might use different Colour Sequence Indicators.

I would suggest you try using ncurses. Other than colour, ncurses can do many other neat things with console UI.

13

You can assign one color to every functionality to make it more useful.

#define Color_Red "\33[0:31m\\]" // Color Start
#define Color_end "\33[0m\\]" // To flush out prev settings
#define LOG_RED(X) printf("%s %s %s",Color_Red,X,Color_end)

foo()
{
LOG_RED("This is in Red Color");
}

Like wise you can select different color codes and make this more generic.

Praveen S
  • 10,355
  • 2
  • 43
  • 69
11

You can output special color control codes to get colored terminal output, here's a good resource on how to print colors.

For example:

printf("\033[22;34mHello, world!\033[0m");  // shows a blue hello world

EDIT: My original one used prompt color codes, which doesn't work :( This one does (I tested it).

Stephen
  • 47,994
  • 7
  • 61
  • 70
  • `edition.c: In function ‘int main(int, const char**)’: edition.c:4: error: unknown escape sequence '\]' edition.c:4: error: unknown escape sequence '\]' edition.c edition.c~` Nothing more than a bunch of compile errors :( –  Jul 10 '10 at 13:45
  • Also, my application should not be dependent on BASH. –  Jul 10 '10 at 13:46
  • @Koning : This isn't BASH dependent, it works in other shells too (but I'm sure not all). I verified in ksh, and csh. Note I edited the control code to work properly. – Stephen Jul 10 '10 at 13:59
  • 2
    It won't be. It depends on terminal emulation. If it is ANSI understanding ANSI escape sequences, then you'll have your colours, bold, or whatever. – ShinTakezou Jul 10 '10 at 14:53
  • @Stephen *Bonus:* Change `22` by `1` to see it in **bold**. – hola Jul 31 '14 at 11:17
8
#include <stdio.h>

#define BLUE(string) "\x1b[34m" string "\x1b[0m"
#define RED(string) "\x1b[31m" string "\x1b[0m"

int main(void)
{
    printf("this is " RED("red") "!\n");

    // a somewhat more complex ...
    printf("this is " BLUE("%s") "!\n","blue");

    return 0;
}

reading Wikipedia:

  • \x1b[0m resets all attributes
  • \x1b[31m sets foreground color to red
  • \x1b[44m would set the background to blue.
  • both : \x1b[31;44m
  • both but inversed : \x1b[31;44;7m
  • remember to reset afterwards \x1b[0m ...
Veles
  • 119
  • 1
  • 3
4

If you use same color for whole program , you can define printf() function.

   #include<stdio.h>
   #define ah_red "\e[31m"
   #define printf(X) printf(ah_red "%s",X);
   #int main()
   {
        printf("Bangladesh");
        printf("\n");
        return 0;
   }
alhelal
  • 916
  • 11
  • 27
3

Because you can't print a character with string formating. You can also think of adding a format with something like this

#define PRINTC(c,f,s) printf ("\033[%dm" f "\033[0m", 30 + c, s)

f is format as in printf

PRINTC (4, "%s\n", "bar")

will print blue bar

PRINTC (1, "%d", 'a')

will print red 97

phuclv
  • 37,963
  • 15
  • 156
  • 475
baz
  • 1,317
  • 15
  • 10
1

Expanding on the answer of @AndrejsCainikovs, here is a code that works for 24-bits rgb code (both for font and background color) with terminals that supports such code (Xterm, KDE's Konsole, and iTerm, as well as all libvte based terminals, including GNOME Terminal according to https://en.wikipedia.org/wiki/ANSI_escape_code#Colors):

#include <stdio.h>

#define ANSI_FONT_COL_RESET     "\x1b[0m"
#define FONT_COL_CUSTOM_RED     "\e[38;2;200;0;0m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define FONT_COL_CUSTOM_GREEN   "\e[38;2;0;200;0m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define FONT_COL_CUSTOM_BLUE    "\e[38;2;0;0;200m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_RED   "\e[48;2;200;0;0m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_GREEN "\e[48;2;0;200;0m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_BLUE  "\e[48;2;0;0;200m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively

int main (int argc, char const *argv[]) {

  printf(FONT_COL_CUSTOM_RED     "This font color is CUSTOM_RED!"           ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_GREEN   "This font color is CUSTOM_GREEN!"         ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_BLUE    "This font color is CUSTOM_BLUE!"          ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_RED   "This background color is CUSTOM_RED!"     ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_GREEN "This background color is CUSTOM_GREEN!"   ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_BLUE  "This background color is CUSTOM_BLUE!"    ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_GREEN BCKGRD_COL_CUSTOM_RED "This font color is CUSTOM_GREEN with background CUSTOM_RED!"    ANSI_FONT_COL_RESET "\n");
  printf(                        "This font color is NORMAL!\n");

  return 0;
}
ecjb
  • 5,169
  • 12
  • 43
  • 79