stdlib и цветной вывод на C


125

Я делаю простое приложение, требующее цветного вывода. Как я могу сделать свой вывод цветным, как emacs и bash?

Меня не волнует Windows, поскольку мое приложение предназначено только для систем UNIX.

Ответы:


288

Все современные эмуляторы терминала используют escape-коды ANSI для отображения цветов и прочего.
Не беспокойтесь о библиотеках, код действительно прост.

Больше информации здесь .

Пример на C:

#include <stdio.h>

#define ANSI_COLOR_RED     "\x1b[31m"
#define ANSI_COLOR_GREEN   "\x1b[32m"
#define ANSI_COLOR_YELLOW  "\x1b[33m"
#define ANSI_COLOR_BLUE    "\x1b[34m"
#define ANSI_COLOR_MAGENTA "\x1b[35m"
#define ANSI_COLOR_CYAN    "\x1b[36m"
#define ANSI_COLOR_RESET   "\x1b[0m"

int main (int argc, char const *argv[]) {

  printf(ANSI_COLOR_RED     "This text is RED!"     ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_GREEN   "This text is GREEN!"   ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_YELLOW  "This text is YELLOW!"  ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_BLUE    "This text is BLUE!"    ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_MAGENTA "This text is MAGENTA!" ANSI_COLOR_RESET "\n");
  printf(ANSI_COLOR_CYAN    "This text is CYAN!"    ANSI_COLOR_RESET "\n");

  return 0;
}

1
Но я полагаю, что могу запустить bash в эмуляции терминала, которая не поддерживает escape-последовательности ANSI.
ShinTakezou

Хороший флаг :) Просто гнида, что вопрос помечен как «c», а не «c ++»
Стивен

@ShinTakezou: Да ... В этом случае все escape-коды ANSI будут проигнорированы, и у вас не будет вариантов для создания необычного вывода.
Андрей Кайниковс

14
Управляющие последовательности ANSI не интерпретируются оболочками, они интерпретируются эмуляторами терминала.
ninjalj

6
Особенно понравилась фраза «Не беспокойтесь о библиотеках»! Коды ANSI работают даже в командной строке Windows.
SzG

15

Работа с цветовыми последовательностями может стать беспорядочной, и разные системы могут использовать разные индикаторы цветовой последовательности.

Я предлагаю вам попробовать использовать ncurses . Помимо цвета, ncurses может делать много других полезных вещей с консольным UI.


Является ли использование разных цветовых последовательностей причиной того, что я не могу найти файл "colors.h" со всей проделанной за меня работой?
Cool Javelin

10

Вы можете выводить специальные коды управления цветом, чтобы получить цветной вывод терминала, вот хороший ресурс о том, как печатать цвета .

Например:

printf("\033[22;34mHello, world!\033[0m");  // shows a blue hello world

РЕДАКТИРОВАТЬ: В моем оригинальном использовались цветовые коды подсказок, которые не работают :( Этот работает (я его тестировал).


edition.c: In function ‘int main(int, const char**)’: edition.c:4: error: unknown escape sequence '\]' edition.c:4: error: unknown escape sequence '\]' edition.c edition.c~Ничего, кроме кучи ошибок компиляции :(

Кроме того, мое приложение не должно зависеть от BASH.

@Koning: это не зависит от BASH, он работает и в других оболочках (но я уверен, что не во всех). Проверял в ksh и csh. Примечание. Я отредактировал управляющий код, чтобы он работал правильно.
Стивен

2
Не будет. Это зависит от эмуляции терминала. Если это ANSI, понимающий escape-последовательности ANSI, тогда у вас будут свои цвета, жирный шрифт или что-то еще.
ShinTakezou

@Stephen Bonus: измените значение 22на, 1чтобы выделить его жирным шрифтом .
xxx ---

9

Вы можете назначить один цвет для каждой функции, чтобы сделать ее более полезной.

#define Color_Red "\33[0:31m\\]" // Color Start
#define Color_end "\33[0m\\]" // To flush out prev settings
#define LOG_RED(X) printf("%s %s %s",Color_Red,X,Color_end)

foo()
{
LOG_RED("This is in Red Color");
}

Вы также можете выбрать разные цветовые коды и сделать их более общими.


3

Если вы используете один и тот же цвет для всей программы, вы можете определить printf()функцию.

   #include<stdio.h>
   #define ah_red "\e[31m"
   #define printf(X) printf(ah_red "%s",X);
   #int main()
   {
        printf("Bangladesh");
        printf("\n");
        return 0;
   }

2

Потому что вы не можете напечатать символ с форматированием строки. Вы также можете подумать о добавлении формата с чем-то вроде этого

#define PRINTC(c,f,s) printf ("\033[%dm" f "\033[0m", 30 + c, s)

f формат как в printf

PRINTC (4, "%s\n", "bar")

напечатает blue bar

PRINTC (1, "%d", 'a')

напечатает red 97


2
#include <stdio.h>

#define BLUE(string) "\x1b[34m" string "\x1b[0m"
#define RED(string) "\x1b[31m" string "\x1b[0m"

int main(void)
{
    printf("this is " RED("red") "!\n");

    // a somewhat more complex ...
    printf("this is " BLUE("%s") "!\n","blue");

    return 0;
}

читая Википедию :

  • \ x1b [0m сбрасывает все атрибуты
  • \ x1b [31m устанавливает красный цвет переднего плана
  • \ x1b [44m установит синий фон.
  • оба: \ x1b [31; 44m
  • оба, но перевернутые: \ x1b [31; 44; 7m
  • не забудьте потом сбросить \ x1b [0m ...
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.