Как печатать цветные символы на терминал Linux, который его поддерживает?
Как узнать, поддерживает ли терминал цветовые коды?
Я использую С++ для этой программы.
Как печатать цветные символы на терминал Linux, который его поддерживает?
Как узнать, поддерживает ли терминал цветовые коды?
Я использую С++ для этой программы.
Вам нужно вывести цветовые коды ANSI. Обратите внимание, что не все терминалы поддерживают это; если цветовые последовательности не поддерживаются, появится мусор.
Пример:
cout << "\033[1;31mbold red text\033[0m\n";
Здесь \033
- символ ESC, ASCII 27. За ним следует [
, затем ноль или более чисел, разделенных символом ;
, и, наконец, буква m
. Цифры описывают цвет и формат для перехода с этой точки вперед.
Коды цветов переднего плана и фона:
foreground background
black 30 40
red 31 41
green 32 42
yellow 33 43
blue 34 44
magenta 35 45
cyan 36 46
white 37 47
Кроме того, вы можете использовать их:
reset 0 (everything back to normal)
bold/bright 1 (often a brighter shade of the same colour)
underline 4
inverse 7 (swap foreground and background colours)
bold/bright off 21
underline off 24
inverse off 27
См. таблицу в Википедии для других, менее широко поддерживаемых кодов.
Изменить. Чтобы определить, поддерживает ли ваш терминал цветовые последовательности, прочитайте значение переменной среды TERM
. Он должен указать конкретный тип терминала (например, vt100
, gnome-terminal
, xterm
, screen
,...). Затем посмотрите на базу данных terminfo; проверьте возможность colors
.
Я написал класс С++, который можно использовать для установки цвета переднего и заднего фона. Эта примерная программа служит примером печати This ->word<- is red.
и форматирования ее так, чтобы цвет переднего плана word
был красным.
#include "colormod.h" // namespace Color
#include <iostream>
using namespace std;
int main() {
Color::Modifier red(Color::FG_RED);
Color::Modifier def(Color::FG_DEFAULT);
cout << "This ->" << red << "word" << def << "<- is red." << endl;
}
#include <ostream>
namespace Color {
enum Code {
FG_RED = 31,
FG_GREEN = 32,
FG_BLUE = 34,
FG_DEFAULT = 39,
BG_RED = 41,
BG_GREEN = 42,
BG_BLUE = 44,
BG_DEFAULT = 49
};
class Modifier {
Code code;
public:
Modifier(Code pCode) : code(pCode) {}
friend std::ostream&
operator<<(std::ostream& os, const Modifier& mod) {
return os << "\033[" << mod.code << "m";
}
};
}
Вы можете добавить дополнительные функции в класс. Например, можно добавить цвет пурпурного и даже стилей, например жирный шрифт. Для этого просто введите другую запись в перечисление Code
. Это является хорошей ссылкой.
Перед тем, как вы выведете любой цвет, вам нужно убедиться, что вы находитесь в терминале:
[ -t 1 ] && echo 'Yes I am in a terminal' # isatty(3) call in C
Затем вам нужно проверить возможности терминала, если он поддерживает цвет
в системах с terminfo
(на основе Linux) вы можете получить количество поддерживаемых цветов как
Number_Of_colors_Supported=$(tput colors)
в системах с termcap
(основанный на BSD) вы можете получить количество поддерживаемых цветов как
Number_Of_colors_Supported=$(tput Co)
Затем сделайте свое решение:
[ ${Number_Of_colors_Supported} -ge 8 ] && {
echo 'You are fine and can print colors'
} || {
echo 'Terminal does not support color'
}
Кстати, не используйте окраску, как было предложено ранее, с символами ESC. Используйте стандартный вызов для возможности терминала, который назначит вам ПРАВИЛЬНЫЕ цвета, которые поддерживают конкретный терминал.
Основанный на BSDfg_black="$(tput AF 0)"
fg_red="$(tput AF 1)"
fg_green="$(tput AF 2)"
fg_yellow="$(tput AF 3)"
fg_blue="$(tput AF 4)"
fg_magenta="$(tput AF 5)"
fg_cyan="$(tput AF 6)"
fg_white="$(tput AF 7)"
reset="$(tput me)"
На основе Linux
fg_black="$(tput setaf 0)"
fg_red="$(tput setaf 1)"
fg_green="$(tput setaf 2)"
fg_yellow="$(tput setaf 3)"
fg_blue="$(tput setaf 4)"
fg_magenta="$(tput setaf 5)"
fg_cyan="$(tput setaf 6)"
fg_white="$(tput setaf 7)"
reset="$(tput sgr0)"
Использовать как
echo -e "${fg_red} Red ${fg_green} Bull ${reset}"
Как утверждали другие, вы можете использовать escape-символы. Вы можете использовать мой заголовок, чтобы сделать его проще:
#ifndef _COLORS_
#define _COLORS_
/* FOREGROUND */
#define RST "\x1B[0m"
#define KRED "\x1B[31m"
#define KGRN "\x1B[32m"
#define KYEL "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMAG "\x1B[35m"
#define KCYN "\x1B[36m"
#define KWHT "\x1B[37m"
#define FRED(x) KRED x RST
#define FGRN(x) KGRN x RST
#define FYEL(x) KYEL x RST
#define FBLU(x) KBLU x RST
#define FMAG(x) KMAG x RST
#define FCYN(x) KCYN x RST
#define FWHT(x) KWHT x RST
#define BOLD(x) "\x1B[1m" x RST
#define UNDL(x) "\x1B[4m" x RST
#endif /* _COLORS_ */
Пример использования макросов заголовка может быть:
#include <iostream>
#include "colors.h"
using namespace std;
int main()
{
cout << FBLU("I'm blue.") << endl;
cout << BOLD(FBLU("I'm blue-bold.")) << endl;
return 0;
}
Это старая тема, но я написал класс с вложенными подклассами и статическими членами для цветов, определенных простыми макросами C.
Я получил функцию color
из этого сообщения Цветной текст в программировании на C в dreamincode.net пользователем no2pencil.
Я сделал это так, чтобы иметь возможность использовать статические константы в потоке std:: cout следующим образом:
cout << zkr::cc::fore::red << "This is red text. "
<< zkr::cc::console << "And changing to console default colors, fg, bg."
<< endl;
Класс и исходный код тестовой программы можно загрузить здесь.
cc::console
будет reset для консоли по умолчанию цветов и атрибутов, cc::underline
будет подчеркивать текст, который работает на шпатле, который я тестировал тестовую программу.
Цвет:
black
blue
red
magenta
green
cyan
yellow
white
lightblack
lightblue
lightred
lightmagenta
lightgreen
lightcyan
lightyellow
lightwhite
который может использоваться с статическими подклассами fore
и back
статического класса cc
.
EDIT 2017
Я просто добавляю код класса здесь, чтобы быть более практичным.
Макросы цветового кода:
#define CC_CONSOLE_COLOR_DEFAULT "\033[0m"
#define CC_FORECOLOR(C) "\033[" #C "m"
#define CC_BACKCOLOR(C) "\033[" #C "m"
#define CC_ATTR(A) "\033[" #A "m"
и основная цветовая функция, определяющая цвет или атрибут экрана:
char *cc::color(int attr, int fg, int bg)
{
static char command[13];
/* Command is the control command to the terminal */
sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
return command;
}
ccolor.h
#include <stdio.h>
#define CC_CONSOLE_COLOR_DEFAULT "\033[0m"
#define CC_FORECOLOR(C) "\033[" #C "m"
#define CC_BACKCOLOR(C) "\033[" #C "m"
#define CC_ATTR(A) "\033[" #A "m"
namespace zkr
{
class cc
{
public:
class fore
{
public:
static const char *black;
static const char *blue;
static const char *red;
static const char *magenta;
static const char *green;
static const char *cyan;
static const char *yellow;
static const char *white;
static const char *console;
static const char *lightblack;
static const char *lightblue;
static const char *lightred;
static const char *lightmagenta;
static const char *lightgreen;
static const char *lightcyan;
static const char *lightyellow;
static const char *lightwhite;
};
class back
{
public:
static const char *black;
static const char *blue;
static const char *red;
static const char *magenta;
static const char *green;
static const char *cyan;
static const char *yellow;
static const char *white;
static const char *console;
static const char *lightblack;
static const char *lightblue;
static const char *lightred;
static const char *lightmagenta;
static const char *lightgreen;
static const char *lightcyan;
static const char *lightyellow;
static const char *lightwhite;
};
static char *color(int attr, int fg, int bg);
static const char *console;
static const char *underline;
static const char *bold;
};
}
ccolor.cpp
#include "ccolor.h"
using namespace std;
namespace zkr
{
enum Color
{
Black,
Red,
Green,
Yellow,
Blue,
Magenta,
Cyan,
White,
Default = 9
};
enum Attributes
{
Reset,
Bright,
Dim,
Underline,
Blink,
Reverse,
Hidden
};
char *cc::color(int attr, int fg, int bg)
{
static char command[13];
/* Command is the control command to the terminal */
sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40);
return command;
}
const char *cc::console = CC_CONSOLE_COLOR_DEFAULT;
const char *cc::underline = CC_ATTR(4);
const char *cc::bold = CC_ATTR(1);
const char *cc::fore::black = CC_FORECOLOR(30);
const char *cc::fore::blue = CC_FORECOLOR(34);
const char *cc::fore::red = CC_FORECOLOR(31);
const char *cc::fore::magenta = CC_FORECOLOR(35);
const char *cc::fore::green = CC_FORECOLOR(92);
const char *cc::fore::cyan = CC_FORECOLOR(36);
const char *cc::fore::yellow = CC_FORECOLOR(33);
const char *cc::fore::white = CC_FORECOLOR(37);
const char *cc::fore::console = CC_FORECOLOR(39);
const char *cc::fore::lightblack = CC_FORECOLOR(90);
const char *cc::fore::lightblue = CC_FORECOLOR(94);
const char *cc::fore::lightred = CC_FORECOLOR(91);
const char *cc::fore::lightmagenta = CC_FORECOLOR(95);
const char *cc::fore::lightgreen = CC_FORECOLOR(92);
const char *cc::fore::lightcyan = CC_FORECOLOR(96);
const char *cc::fore::lightyellow = CC_FORECOLOR(93);
const char *cc::fore::lightwhite = CC_FORECOLOR(97);
const char *cc::back::black = CC_BACKCOLOR(40);
const char *cc::back::blue = CC_BACKCOLOR(44);
const char *cc::back::red = CC_BACKCOLOR(41);
const char *cc::back::magenta = CC_BACKCOLOR(45);
const char *cc::back::green = CC_BACKCOLOR(42);
const char *cc::back::cyan = CC_BACKCOLOR(46);
const char *cc::back::yellow = CC_BACKCOLOR(43);
const char *cc::back::white = CC_BACKCOLOR(47);
const char *cc::back::console = CC_BACKCOLOR(49);
const char *cc::back::lightblack = CC_BACKCOLOR(100);
const char *cc::back::lightblue = CC_BACKCOLOR(104);
const char *cc::back::lightred = CC_BACKCOLOR(101);
const char *cc::back::lightmagenta = CC_BACKCOLOR(105);
const char *cc::back::lightgreen = CC_BACKCOLOR(102);
const char *cc::back::lightcyan = CC_BACKCOLOR(106);
const char *cc::back::lightyellow = CC_BACKCOLOR(103);
const char *cc::back::lightwhite = CC_BACKCOLOR(107);
}
Я использую следующее решение: оно довольно простое и изящное, легко вставляется в исходный код и работает на Linux/ Bash:
const std::string red("\033[0;31m");
const std::string green("\033[1;32m");
const std::string yellow("\033[1;33m");
const std::string cyan("\033[0;36m");
const std::string magenta("\033[0;35m");
const std::string reset("\033[0m");
std::cout << "Measured runtime: " << yellow << timer.count() << reset << std::endl;
Вы можете использовать escape-последовательности, если ваш терминал поддерживает его. Например:
echo \[\033[32m\]Hello, \[\033[36m\]colourful \[\033[33mworld!\033[0m\]
Вы можете использовать цветовые коды ANSI.
используйте эти функции.
enum c_color{BLACK=30,RED=31,GREEN=32,YELLOW=33,BLUE=34,MAGENTA=35,CYAN=36,WHITE=37};
enum c_decoration{NORMAL=0,BOLD=1,FAINT=2,ITALIC=3,UNDERLINE=4,RIVERCED=26,FRAMED=51};
void pr(const string str,c_color color,c_decoration decoration=c_decoration::NORMAL){
cout<<"\033["<<decoration<<";"<<color<<"m"<<str<<"\033[0m";
}
void prl(const string str,c_color color,c_decoration decoration=c_decoration::NORMAL){
cout<<"\033["<<decoration<<";"<<color<<"m"<<str<<"\033[0m"<<endl;
}
С моей точки зрения, типичный цветовой код ANSI
"\033[{FORMAT_ATTRIBUTE};{FORGROUND_COLOR};{BACKGROUND_COLOR}m{TEXT}\033[{RESET_FORMATE_ATTRIBUTE}m"
состоит из (имя и кодек)
ФОРМАТ АТРИБУТ
{ "Default", "0" },
{ "Bold", "1" },
{ "Dim", "2" },
{ "Underlined", "3" },
{ "Blink", "5" },
{ "Reverse", "7" },
{ "Hidden", "8" }
ИСТОРИЧЕСКИЙ ЦВЕТ
{ "Default", "39" },
{ "Black", "30" },
{ "Red", "31" },
{ "Green", "32" },
{ "Yellow", "33" },
{ "Blue", "34" },
{ "Magenta", "35" },
{ "Cyan", "36" },
{ "Light Gray", "37" },
{ "Dark Gray", "90" },
{ "Light Red", "91" },
{ "Light Green", "92" },
{ "Light Yellow", "93" },
{ "Light Blue", "94" },
{ "Light Magenta", "95" },
{ "Light Cyan", "96" },
{ "White", "97" }
ЦВЕТ ВОСПРОИЗВЕДЕНИЯ
{ "Default", "49" },
{ "Black", "40" },
{ "Red", "41" },
{ "Green", "42" },
{ "Yellow", "43" },
{ "Blue", "44" },
{ "Megenta", "45" },
{ "Cyan", "46" },
{ "Light Gray", "47" },
{ "Dark Gray", "100" },
{ "Light Red", "101" },
{ "Light Green", "102" },
{ "Light Yellow", "103" },
{ "Light Blue", "104" },
{ "Light Magenta", "105" },
{ "Light Cyan", "106" },
{ "White", "107" }
ТЕКСТ
RESET ФОРМАТ АТРИБУТ
{ "All", "0" },
{ "Bold", "21" },
{ "Dim", "22" },
{ "Underlined", "24" },
{ "Blink", "25" },
{ "Reverse", "27" },
{ "Hidden", "28" }
С этой информацией легко раскрасить строку "Я банан!". с фоном цвет "Желтый" и цвет фона "Зеленый", как этот
"\033[0;33;42mI am a Banana!\033[0m"
Или с библиотекой С++ colorize
auto const& colorized_text = color::rize( "I am a banana!", "Yellow", "Green" );
std::cout << colorized_text << std::endl;
Лучший способ - использовать библиотеку ncurses - хотя это может быть кувалдой, чтобы взломать орех, если вы просто хотите вывести простую цветную строку
на оболочке OSX это работает для меня (в том числе 2 пробела перед "красным текстом" ):
$ printf "\e[033;31m red text\n"
$ echo "$(tput setaf 1) red text"
попробуйте мой заголовок здесь для быстрого и легкого способа цветного текста: Aedi Color Header
Цветной вывод в Unix с помощью С++!
ATTRIBUTES_OFF, BOLD, UNDERSCORE, BLINK, REVERSE_VIDEO, CONCEALED
BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE
Общий формат, укажите значение, которое вы хотите в переменной $$
COLOR_$Foreground_Color$_$Background_Color$
COLOR_$Text_Attribute$_$Foreground_Color$_$Background_Color$
COLOR_NORMAL // To set color to default
например.
COLOR_BLUE_BLACK // Leave Text Attribute Blank if no Text Attribute appied
COLOR_UNDERSCORE_YELLOW_RED
COLOR_NORMAL
Просто используйте для потоковой передачи цвета, который вы хотите, прежде чем выводить текст и используйте снова, чтобы установить цвет в нормальное состояние после вывода текста.
cout << COLOR_BLUE_BLACK << "TEXT" << COLOR_NORMAL << endl;
cout << COLOR_BOLD_YELLOW_CYAN << "TEXT" << COLOR_NORMAL << endl;