Иногда встает вопрос, как в программе Unix выводить в консоль через printf текст сообщения разными цветами?
В Unix-подобных системах (Linux) можно выводить цветной текст в консоль с помощью управляющих последовательностей ANSI (ANSI escape codes). Эти коды встраиваются прямо в строку, которую вы передаёте в printf.
Основной формат:
printf("\033[КодЦветаТекста;КодЦветаФонаmТекст\033[0m");
Здесь:
\033 — это Escape-символ (можно также писать \e или \x1b).
[ — начало управляющей последовательности.
КодЦветаТекста;КодЦветаФона — числовые коды цветов (см. таблицу далее).
m — завершает последовательность.
\033[0m — сброс цветов в стандартные.
Коды основных цветов текста:
Цвет текста |
Код |
Чёрный |
30 |
Красный |
31 |
Зелёный |
32 |
Жёлтый |
33 |
Синий |
34 |
Пурпурный |
35 |
Голубой |
36 |
Белый |
37 |
Стандартный |
39 |
Коды фона (добавляем 10):
Цвет фона |
Код |
Чёрный |
40 |
Красный |
41 |
Зелёный |
42 |
Жёлтый |
43 |
Синий |
44 |
Пурпурный |
45 |
Голубой |
46 |
Белый |
47 |
Стандартный |
49 |
Простой пример на языке C:
#include < stdio.h>
int main() {
// Красный текст
printf("\033[31mЭтот текст красный\033[0m\n");
// Зелёный текст на чёрном фоне
printf("\033[32;40mЗелёный на чёрном\033[0m\n");
// Жёлтый текст с подчёркиванием (доп. стиль)
printf("\033[33;4mЖёлтый и подчёркнутый\033[0m\n");
// Сброс/возврат к стандартному выводу
printf("Обычный текст\n");
return 0;
}
Дополнительные стили текста:
Стиль |
Код |
Сброс стиля |
0 |
Жирный |
1 |
Тонкий |
2 |
Курсив |
3 |
Подчёркивание |
4 |
Мигание |
5 |
Инвертирование |
7 |
Пример:
printf("\033[1;31mЖирный красный текст\033[0m\n"); printf("\033[4;36mПодчёркнутый голубой\033[0m\n");
Проверка поддержки цветов. Некоторые терминалы могут не поддерживать цвета. Проверить поддержку можно так (команда bash):
$ echo -e "\033[31mКрасный\033[0m"
Если цвет не отображается (что особенно актуально для стандартной консоли Windows), попробуйте другой терминал (например putty, xterm, gnome-terminal, konsole).
[Альтернатива: библиотека ncurses]
Если нужно сложное управление терминалом, можно использовать библиотеку ncurses:
#include < ncurses.h>
int main()
{
initscr(); // Инициализация ncurses
start_color();
init_pair(1, COLOR_RED, COLOR_BLACK);
attron(COLOR_PAIR(1));
printw("Красный текст на чёрном фоне");
attroff(COLOR_PAIR(1));
refresh();
getch();
endwin();
return 0;
}
Компиляция:
$ gcc main.c -lncurses
[Пример реализации вывода в лог]
В следующем простом примере реализована функция вывода в лог желтым цветом. Вывод производится с помощью макроса clog, который принимает параметры в таком же виде, как и стандартная функция printf. В начале строки лога выводится метка времени в часах, минутах, секундах и миллисекундах.
Заголовочный файл colored_log.h:
#include < stdint.h>
#define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" #define ANSI_COLOR_DARK_YELLOW "\x1b[33m" #define ANSI_COLOR_YELLOW "\x1b[93m" #define ANSI_COLOR_BLUE "\x1b[34m" #define ANSI_COLOR_MAGENTA "\x1b[35m" #define ANSI_COLOR_CYAN "\x1b[36m" #define ANSI_COLOR_RESET "\x1b[0m"
#define CPRINTF_BUF_SIZE 512
#define clog(...) \
{ \
cprintf(__VA_ARGS__); \
}
void reset_log_milliseconds (void); int16_t cprintf (const char *fmt, ...);
Модуль colored_log.c:
#include < stdio.h> #include < string.h> #include < stdlib.h> #include < stdarg.h> #include < time.h> #include "colored_log.h"
static long long lltimestamp;
long long current_timestamp() {
struct timeval te;
// Получение текущего времени:
gettimeofday(&te, NULL);
// Вычисление абсолютного количества миллисекунд:
long long milliseconds = te.tv_sec*1000LL + te.tv_usec/1000;
return milliseconds; }
void reset_log_milliseconds (void) {
lltimestamp = current_timestamp(); }
// Функция для формирования строки лога в формате: // "HH:MM:SS(мс) текст" // Строка лога будет выведена желтым цветом ANSI_COLOR_YELLOW. // В скобках выводится абсолютное значение в миллисекундах. // Его можно сделать относительным последнего вызова функции // reset_log_milliseconds(). int16_t cprintf (const char *fmt, ...) {
int16_t outsize;
va_list ap;
static char strbuf[CPRINTF_BUF_SIZE];
// Вернет ошибку, если формат является указателем NULL:
if (!fmt) { return -1; }
// Вернет ошибку, если строка превышает размер буфера CPRINTF_BUF_SIZE, с учетом
// необходимых дополнительных 2 символов: CR и нулевой терминатор ASCIIZ:
if (CPRINTF_BUF_SIZE-2 < strlen(fmt)) { return -1; }
// Получение строки времени в формате HH:MM:SS:
time_t ltime;
struct tm *time_info;
char timeString[9]; // буфер для "HH:MM:SS\0"
time(<ime);
time_info = localtime(<ime);
strftime(timeString, sizeof(timeString), "%H:%M:%S", time_info);
va_start (ap,fmt);
outsize = vsprintf(strbuf,fmt,ap);
strbuf[outsize] = 0;
va_end (ap);
// Формирование строки лога в формате:
// "HH:MM:SS(мс) текст"
printf("%s%s(%lld): %s%s", ANSI_COLOR_YELLOW,
timeString,
current_timestamp() - lltimestamp,
strbuf,
ANSI_COLOR_RESET);
return outsize; }
[Ссылки]
1. stdlib and colored output in C site:stackoverflow.com. 2. How to Print Colored Text to the Terminal site:saturncloud.io. 3. How to Change Text Color in a Linux Terminal site:codeproject.com. 4. How to get appropriate timestamp in c for logs? site:stackoverflow.com. 5. time.h time types site:pubs.opengroup.org. |