C语言中的stdlib和彩色输出

163

我正在制作一个简单的应用程序,需要彩色输出。如何使我的输出像emacs和bash一样上色?

由于我的应用程序只针对UNIX系统,因此我不关心Windows。

8个回答

359

现代终端模拟器都使用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;
}

2
但我想我可以在不支持ANSI转义序列的终端仿真器中运行bash。 - ShinTakezou
@白痴:我以为真正的CSI(0x9b)不被一些终端仿真器所识别,但任何理智的、大多数符合ANSI/ECMA-48标准的终端仿真器都能识别7位的CSI(ESC [)。 - ninjalj
@ninjalj:可能吧,但我说实话不是很确定。 - Aryabhatta
10
特别喜欢“不要使用库”的建议!ANSI码甚至可以在Windows命令提示符中工作。 - SzG
@SzG,我在Windows 11命令提示符中尝试了一下,但它不起作用,只是打印转义序列。它只在嵌入在VSCode中的命令提示符中起作用。 - FLAK-ZOSO
显示剩余5条评论

15
处理颜色序列可能会变得混乱,不同的系统可能使用不同的颜色序列指标。
我建议您尝试使用 ncurses。除了颜色之外,ncurses 还可以在控制台 UI 中做许多其他有用的事情。

使用不同的颜色序列是我找不到一个已经完成所有工作的"colors.h"文件的原因吗? - Cool Javelin

13

您可以为每个功能分配一种颜色,使其更有用。

#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");
}

同样地,您可以选择不同的颜色代码并使其更通用。


11
你可以输出特殊的颜色控制代码来获得带有颜色的终端输出,以下是一个关于如何打印颜色的好资源。
例如:
printf("\033[22;34mHello, world!\033[0m");  // shows a blue hello world

编辑:我的原始代码使用提示颜色代码,但不起作用 :( 这个可以(我测试过了)。


edition.c:在函数‘int main(int,const char **)’中: edition.c:4:错误:未知的转义序列‘]’ edition.c:4:错误:未知的转义序列‘]’ edition.c edition.c~ 只是一堆编译错误:( - user142019
此外,我的应用程序不应依赖于BASH。 - user142019
@Koning:这不是BASH特有的,它在其他shell中也可以工作(但我肯定不是所有的)。我在ksh和csh中进行了验证。请注意,我编辑了控制代码以使其正常工作。 - Stephen
2
它不会。这取决于终端仿真。如果它是ANSI,能理解ANSI转义序列,那么您就可以拥有您想要的彩色,加粗或其他效果。 - ShinTakezou
@Stephen 奖励:22更改为1以查看粗体 - hola

8
#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 ...

4
如果您想为整个程序使用相同的颜色,您可以定义 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;
   }

3

因为您不能使用字符串格式打印字符。您还可以考虑添加类似以下内容的格式:

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

f 是指格式化,类似于printf

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

将会打印蓝色条

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

将会打印出red 97


1

在@AndrejsCainikovs的答案基础上,这里提供了一段代码,适用于支持24位RGB代码(包括字体和背景颜色)的终端(如Xterm、KDE的Konsole和iTerm,以及所有基于libvte的终端,包括GNOME终端,参见https://en.wikipedia.org/wiki/ANSI_escape_code#Colors):

#include <stdio.h>

#define ANSI_FONT_COL_RESET     "\x1b[0m"
#define FONT_COL_CUSTOM_RED     "\e[38;2;200;0;0m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define FONT_COL_CUSTOM_GREEN   "\e[38;2;0;200;0m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define FONT_COL_CUSTOM_BLUE    "\e[38;2;0;0;200m" // where rrr;ggg;bbb in 38;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_RED   "\e[48;2;200;0;0m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_GREEN "\e[48;2;0;200;0m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively
#define BCKGRD_COL_CUSTOM_BLUE  "\e[48;2;0;0;200m" // where rrr;ggg;bbb in 48;2;rrr;ggg;bbbm can go from 0 to 255 respectively

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

  printf(FONT_COL_CUSTOM_RED     "This font color is CUSTOM_RED!"           ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_GREEN   "This font color is CUSTOM_GREEN!"         ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_BLUE    "This font color is CUSTOM_BLUE!"          ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_RED   "This background color is CUSTOM_RED!"     ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_GREEN "This background color is CUSTOM_GREEN!"   ANSI_FONT_COL_RESET "\n");
  printf(BCKGRD_COL_CUSTOM_BLUE  "This background color is CUSTOM_BLUE!"    ANSI_FONT_COL_RESET "\n");
  printf(FONT_COL_CUSTOM_GREEN BCKGRD_COL_CUSTOM_RED "This font color is CUSTOM_GREEN with background CUSTOM_RED!"    ANSI_FONT_COL_RESET "\n");
  printf(                        "This font color is NORMAL!\n");

  return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接