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_
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.