10

I read about ANSI-C escape codes here. Tried to use it in C/C++ printf/std::cout to colorize the text outputted to console, but without success.

My attempt:

#include <iostream>
#include <cstdio>

int main() {
    int a=3, b=5;
    int &ref = a;
    ref = b;
    
    //cout << "\155\32\m" << a << b <<'\n'; //here it prints m→m 5, no colored text
    printf("\155\32\m %d",a); //here to it prints same - m→m 5, 

    getchar();
}

How can I use these escape codes to output colored text to console?

Am I missing something?

Also, I remember that in some C++ code I saw a call to this function

textcolor(10);

But it gives compilation errors in g++ and in Visual Studio. Which compiler had this function available? Any details?

starball
  • 20,030
  • 7
  • 43
  • 238
goldenmean
  • 18,376
  • 54
  • 154
  • 211

10 Answers10

11

I'm afraid you forgot the ESC character:

#include <cstdio>

int main()
{
    printf("%c[%dmHELLO!\n", 0x1B, 32);
}

Unfortunately it will only work on consoles that support ANSI escape sequences (like a linux console using bash, or old Windows consoles that used ansi.sys)

Nate C-K
  • 5,744
  • 2
  • 29
  • 45
pau.estalella
  • 2,197
  • 1
  • 15
  • 20
  • 2
    @pau.estella - thanks but it still does not print color. Instead it prints ←[32mHELLO! Also can u pls. explain how this printf("%c[%dmHELLO!\n", 0x1B, 32); works. – goldenmean Sep 14 '11 at 11:01
  • 1
    @goldenmean If this answer did not work for you, maybe you should accept some other answer. – VLL Mar 04 '20 at 12:21
  • Alternatively, you can use `\xNN` notation to define a character code for `ESC` in the string, where `NN` is an hexadecimal code of the symbol (`0x1B` == 27 decimal). Also you can separate the string into several parts to make the code more clear (note that string literals `"..."` will be merged together by the compiler): `printf ("\x1B" "[%dm" "HELLO!\n", 32);` See also @Baltasarq answer and comments below. – ded32 Sep 25 '20 at 22:09
  • Actually, Windows 10+ now offers the same capability for applications. I think you have to enable it, but not only is ANSI VT100 like text output back, but just about the entire Console API is deprecated. – TJ Bandrowsky Jul 11 '21 at 00:51
7

I created a very simple text-management library some time ago, being multiplatform, it uses native API calls for Windows and ANSI escape sequences for the rest of the platforms. It is fully documented and you can also browse the source code.

About your specific question, I think you are missing some codes. For example, in order to change the color of text, you should use something like:

static const char * CSI = "\33[";
printf( "%s%s", CSI, "31m" );   // RED

Hope this helps.

Baltasarq
  • 12,014
  • 3
  • 38
  • 57
  • thanks for info. But I guess the ANSI escape sequences for colorizing text only works on DOS consoles. In windows cmd, it prints out some control chars rather than colored text. – goldenmean Sep 14 '11 at 11:06
  • @goldenmean, yes, for Windows command consoles, you must use Windows API calls. The library I pointed you to automatizes this. – Baltasarq Sep 14 '11 at 11:38
  • 1
    I'm almost tempted to suggest that preprocessor macros would be useful in this case, so you can write you rstring as `printf("Hello" COLOR_RED " World" COLOR_OFF);`. – Kerrek SB Sep 14 '11 at 12:40
6

under windows 10 one can use VT100 style by activating the VT100 mode in the current console :

#include <windows.h>
#include <iostream>

#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define DISABLE_NEWLINE_AUTO_RETURN  0x0008

int main()
{       
   HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
   DWORD consoleMode;
   GetConsoleMode( handleOut , &consoleMode);
   consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
   consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;            
   SetConsoleMode( handleOut , consoleMode );

   for (int i = 0; i < 10; ++i)
   {
      std::cout << "\x1b[38;2;" << 5 * i << ";" << 255 - 10 * i << ";220m" 
             << "ANSI Escape Sequence " << i << std::endl;
   }
}

see msdn page : [https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences][1]

user2019716
  • 587
  • 4
  • 13
5

A note to anybody reading this post: https://en.wikipedia.org/wiki/ANSI_escape_code#DOS_and_Windows

In 2016, Microsoft released the Windows 10 Version 1511 update which unexpectedly implemented support for ANSI escape sequences. The change was designed to complement the Windows Subsystem for Linux, adding to the Windows Console Host used by Command Prompt support for character escape codes used by terminal-based software for Unix-like systems. This is not the default behavior and must be enabled programmatically with the Win32 API via SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING)

VLL
  • 9,634
  • 1
  • 29
  • 54
Shades
  • 667
  • 1
  • 7
  • 22
3

ANSI escape codes worked on DOS using the ansi.sys device driver. They won't work windows xp or higher. You need to use the console API SetConsoleTextAttribute()

textcolor was available in the borland turbo c++ compiler.

2

Windows 10 supports ANSI Escape Sequences on the VT100 and derived terminal emulator technologies with 256 color extension. Description and examples are on the page Console Virtual Terminal Sequences.

std::ostringstream ss;
for (int i = 0; i < 10; ++i)
    ss << "\x1b[38;2;" << 5 * i << ";" << 255 - 10 * i << ";220m" 
        << "ANSI Escape Sequence " << i << std::endl;   
std::cout << ss.str();
stansy
  • 135
  • 1
  • 10
1

ANSI formatting codes aren't supported in windows.

http://en.wikipedia.org/wiki/ANSI_escape_code

Cubic
  • 14,902
  • 5
  • 47
  • 92
  • As I said in my answer, Windows does support ANSI codes now, as long as the user is running at least the Threshold 2 version of Windows 10. – Shades Sep 22 '18 at 16:38
  • The 105xx builds was the only builds having VT100 sequences enabled by default. In previous and later builds it's disabled by default cause it was enabled by mistake. See here for the explanation wpdev.uservoice.com/forums/… – JMS Jun 18 '19 at 17:32
  • FYI, in latest Windows 10, you can enable ANSI in conhost via the following reghack -- in HKCU\Console create a DWORD named VirtualTerminalLevel and set it to 0x1; then restart cmd.exe. -- You can test it with the following powershell "?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);. – JMS Jun 18 '19 at 17:33
  • It's always enabled, and what @JMS wrote in the first comment is not true, it wasn't enabled by mistake, It was enabled so that applications that use ANSI formatting codes work correctly without displaying unwanted characters in the command line window and of course to make it easier to categorize certain words in the command line by color. –  Feb 03 '20 at 15:27
  • @BosnianCoder You are right my comment from 10/2018 is old. Windows Terminal, introduced in 2019, supports ANSI sequences by default, See **[Windows and Dos](https://en.wikipedia.org/wiki/ANSI_escape_code)** – JMS Feb 03 '20 at 17:09
0

This will work in any OS that support ANSI escape sequence

#include <iostream>
    
void printColored(char r, char g, char b, char _char_) {
  std::cout << '\33' << '[' << '38' << ';' << '2' << ';' << r << ';' << g << ';' << b << 'm' << _char_ << '\33' << '[' << 'm'
}

Note:

char r is your red in RGB

char g is your green in RGB

char b is your blue in RGB

char char is you character to print in colored text

This may be been answered about using ANSI Escape to output RGB colored text at ANSI Color Specific RGB Sequence Bash

If you think that not true just edit it then i will accept the modification

edbighead
  • 5,607
  • 5
  • 29
  • 35
Blanket Fox
  • 377
  • 4
  • 15
0

Colorization ANSI escape codes use Select Graphic Rendition (SGR) sequences, which are of the form CSI n m, where a CSI (which stands for Control Sequence Introducer) sequence is just the escape character followed by an opening square brace, n is some parameter, and m is the literal "m" character.

The tricky part is really just getting the escape character in a C++ string literal. You can see https://en.cppreference.com/w/cpp/language/escape for info about string escapes in C++. The TL;DR is that you can use octal form like \nnn, or hexadecimal form like \xn.... The ESC character in ASCII is value 27, which in octal is 33, and in hexadecimal, is 1b. So you can either use "\033[...m" or "\x1b[...m".

For example:

"\033[31mred \033[33myellow \033[32mgreen \033[36mcyan \033[34mblue \033[35mmagenta"
"\x1b[31mred \x1b[33myellow \x1b[32mgreen \x1b[36mcyan \x1b[34mblue \x1b[35mmagenta"

(fun fact: Bash uses similar escape sequences for strings, so you can echo -e the above string literals in a Bash shell and it will also work)

For C++20, I use the following snippet in a header file in one of my projects to define some more readable constants:

#include <string_view>

struct SgrPair final {
    std::string_view on;
    std::string_view off;
};
#if USE_ANSI_ESC
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {(ON_STR)}, .off {(OFF_STR)} };
#else
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {""}, .off {""} };
#endif

SGR(dim, "\033[2m",  "\033[22m")
SGR(red, "\033[31m", "\033[39m")

#undef SGR

In the above snippet, the user doing the compilation can choose whether or not to define the USE_ANSI_ESC macro to a truthy value.

See also List of ANSI color escape sequences and https://www.ecma-international.org/publications-and-standards/standards/ecma-48/.

Windows pain and suffering fun

If your program is printed to a Windows console like cmd, you need to write something in your program to enable ANSI escape codes in that console (see https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences):

#ifdef _WIN32
#include <windows.h>
#endif

int main() {
    // ...
    #ifdef _WIN32
    DWORD con_mode;
    GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &con_mode);
    con_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), con_mode);
    // ...
}

The other answers already touched on this, but I added some preprocessor wrapping to make it easier to compile on non-Windows platforms without changing the code.

What "textcolor" is

It's a Turbo C/C++ Compiler function. See page 384 of the Turbo C/C++ Compiler 2.0 docs. See also: conio.h doesn't contain textcolor()?.

starball
  • 20,030
  • 7
  • 43
  • 238
-1

I had this problem a while ago, too, using GCC on Windows 10. I had to set the following registry key to get it to work. [HKEY_CURRENT_USER\Console] "VirtualTerminalLevel"=dword:00000001

Cleverhans
  • 19
  • 1