Search code examples
c++textconsolemacroscommand-line-interface

C++ print colored text in cross-platform


I implemented my own way of printing colored texts in cross-platform. However, I used macros. Is this a bad practice or something that should be avoided? If so, what alternative methods would you recommend?

Code:

#ifndef CLIOUTPUT_H_
#include <stdio.h>
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)
    #include <Windows.h>
    #define _RED     0x0C
    #define _GREEN   0x0A
    #define _DEFAULT 0x0F
    HANDLE __c = GetStdHandle(STD_OUTPUT_HANDLE);
    #define _COLOREDTEXT(_msg, _color) do { \
        SetConsoleTextAttribute(__c, _color); \
        printf("%s", _msg); \
        SetConsoleTextAttribute(__c, _DEFAULT); \
    } while(false)

#elif __APPLE__ || __linux__
    #define _RED     31
    #define _GREEN   32
    #define _DEFAULT \033[0m

    #define _COLOREDTEXT(_msg, _color) do { \
        printf("\033[0;%dm%s\033[0m", _color, _msg); \
    } while(false)

#else
# error "Error"
#endif
#define CLIOUTPUT_H_
#endif // CLIOUTPUT_H_


Solution

  • No macros are not bad pratice, on the contrary on certain case they are a must-use and allows a much better control over the way your code works and compile on different OS. Although they can be difficult to use correctly. One common use case for macros are different library include (which can differ depending on the OS you're building for) or for DEBUG:

    #ifdef DEBUG_MODE
        // Code to execute in debug mode
        // e.g: printing values of a data structure or state of your program
    #endif
    

    This is useful if you need a DEBUG_MODE for your code, to display some information in the console.

    I would still recommend to use enums or constants when possible instead of macros, because they are easier to debug and have a better type safety.

    In your case I think macros are a good choice since the color code differs based on the OS you're using ! But I'll probably define the functions COLOREDTEXT in C/C++ instead since it allows to control the type of the variables.