如何使用 ANSI Escape 代码在控制台上输出彩色文本

Posted

技术标签:

【中文标题】如何使用 ANSI Escape 代码在控制台上输出彩色文本【英文标题】:How to use the ANSI Escape code for outputting colored text on Console 【发布时间】:2011-11-16 22:00:21 【问题描述】:

我读到了 ANSI-C 转义码 here。尝试在 C/C++ printf/cout 中使用它来着色输出到 consolde 但没有成功的文本。

代码:

#include <iostream>

 #include <cstdio>

int main()


    int a=3, b=5;
    int &ref = a;

    ref = b;

    //cout << "\155\32\m" << a << b <<'\n'; //here it prints m→m 5, no colored text
    printf("\155\32\m %d",a); //here to it prints same - m→m 5, 

    getchar();


如何使用这些转义码将彩色文本输出到控制台?

我错过了什么吗?

编辑:在一些 C++ 代码中我看到了对该函数的调用

textcolor(10);

但它会在 g++ 和 Visual Studio 中产生编译错误。哪个编译器有这个功能?有详细信息吗?

【问题讨论】:

【参考方案1】:

恐怕你忘记了 ESC 字符:

#include <cstdio>

int main()

    printf("%c[%dmHELLO!\n", 0x1B, 32);

不幸的是,它仅适用于支持 ANSI 转义序列的控制台(例如使用 bash 的 linux 控制台,或使用 ansi.sys 的旧 Windows 控制台)

【讨论】:

@pau.estella - 谢谢,但它仍然不打印颜色。相反,它打印 ←[32mHELLO!你也可以吗?解释一下这个 printf("%c[%dmHELLO!\n", 0x1B, 32);工作。 @goldenmean 如果这个答案对你不起作用,也许你应该接受其他答案。 或者,您可以使用\xNN 表示法在字符串中为ESC 定义字符代码,其中NN 是符号的十六进制代码(0x1B == 十进制数) .您还可以将字符串分成几个部分以使代码更清晰(注意字符串文字"..." 将由编译器合并在一起):printf ("\x1B" "[%dm" "HELLO!\n", 32); 另见@Baltasarq 答案和下面的 cmets。 实际上,Windows 10+ 现在为应用程序提供了相同的功能。我认为你必须启用它,但不仅是 ANSI VT100 像文本输出一样,而且几乎整个控制台 API 都被弃用了。【参考方案2】:

我前段时间创建了一个非常 simple text-management library,它是多平台的,它使用 Windows 的本机 API 调用和其余平台的 ANSI 转义序列。它有完整的文档,您也可以浏览源代码。

关于您的具体问题,我认为您缺少一些代码。例如,为了改变文本的颜色,你应该使用类似的东西:

static const char * CSI = "\33[";
printf( "%s%s", CSI, "31m" );   // RED

希望这会有所帮助。

【讨论】:

感谢您的信息。但我猜想用于着色文本的 ANSI 转义序列仅适用于 DOS 控制台。在 windows cmd 中,它打印出一些控制字符而不是彩色文本。 @goldenmean,是的,对于 Windows 命令控制台,您必须使用 Windows API 调用。我指给你的库可以自动执行此操作。 我几乎想建议预处理器宏在这种情况下会很有用,所以你可以把你的 rstring 写成printf("Hello" COLOR_RED " World" COLOR_OFF);【参考方案3】:

给任何阅读这篇文章的人的注意事项:https://en.wikipedia.org/wiki/ANSI_escape_code#DOS_and_Windows

2016 年,Microsoft 发布了 Windows 10 版本 1511 更新,意外实现了对 ANSI 转义序列的支持。该更改旨在补充 Linux 的 Windows 子系统,增加命令提示符使用的 Windows 控制台主机对类 Unix 系统的基于终端的软件使用的字符转义码的支持。这不是默认行为,必须通过 SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING) 以编程方式使用 Win32 API 启用

【讨论】:

【参考方案4】:

在 windows 10 下,可以通过在当前控制台中激活 VT100 模式来使用 VT100 样式:

#include <windows.h>
#include <iostream>

#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#define DISABLE_NEWLINE_AUTO_RETURN  0x0008

int main()
       
   HANDLE handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
   DWORD consoleMode;
   GetConsoleMode( handleOut , &consoleMode);
   consoleMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
   consoleMode |= DISABLE_NEWLINE_AUTO_RETURN;            
   SetConsoleMode( handleOut , consoleMode );

   for (int i = 0; i < 10; ++i)
   
      std::cout << "\x1b[38;2;" << 5 * i << ";" << 255 - 10 * i << ";220m" 
             << "ANSI Escape Sequence " << i << std::endl;
   

请参阅 msdn 页面:[https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences][1]

【讨论】:

【参考方案5】:

ANSI 转义码使用 ansi.sys 设备驱动程序在 DOS 上工作。他们不会工作 windows xp 或更高版本。你需要使用console APISetConsoleTextAttribute()

textcolor 在 borland turbo c++ 编译器中可用。

【讨论】:

【参考方案6】:

Windows 10 支持 VT100 上的 ANSI 转义序列和具有 256 色扩展的衍生终端仿真器技术。描述和示例在页面Console Virtual Terminal Sequences。

std::ostringstream ss;
for (int i = 0; i < 10; ++i)
    ss << "\x1b[38;2;" << 5 * i << ";" << 255 - 10 * i << ";220m" 
        << "ANSI Escape Sequence " << i << std::endl;   
std::cout << ss.str();

【讨论】:

【参考方案7】:

Windows 不支持 ANSI 格式代码。

http://en.wikipedia.org/wiki/ANSI_escape_code

【讨论】:

正如我在回答中所说,Windows 现在确实支持 ANSI 代码,只要用户至少运行 Windows 10 的阈值 2 版本。 105xx 版本是唯一默认启用 VT100 序列的版本。在以前和以后的版本中,默认情况下它是禁用的,因为它被错误地启用了。请参阅此处以获取解释 wpdev.uservoice.com/forums/... 仅供参考,在最新的 Windows 10 中,您可以通过以下 reghack 在 conhost 中启用 ANSI -- 在 HKCU\Console 创建一个名为 VirtualTerminalLevel 的 DWORD 并将其设置为 0x1;然后重新启动 cmd.exe。 -- 你可以用下面的powershell测试它 "?[1;31mele ?[32mct ?[33mroni ?[35mX ?[36mtar ?[m".Replace('?', [char]27);. 它总是启用的,@JMS 在第一条评论中写的不是真的,它不是错误启用的,启用它是为了使使用 ANSI 格式代码的应用程序正常工作而不会显示不需要的字符在命令行窗口中,当然是为了更容易在命令行中按颜色对某些单词进行分类。 @BosnianCoder 你说得对,我在 2018 年 10 月的评论已经过时了。 Windows Terminal,2019 年推出,默认支持 ANSI 序列,见 Windows and Dos【参考方案8】:

这适用于任何支持 ANSI 转义序列的操作系统

#include <iostream>
    
void printColored(char r, char g, char b, char _char_) 
  std::cout << '\33' << '[' << '38' << ';' << '2' << ';' << r << ';' << g << ';' << b << 'm' << _char_ << '\33' << '[' << 'm'

注意:

char r 是 RGB 中的红色

char g 是 RGB 中的绿色

char b 是 RGB 中的蓝色

char char 是你要在彩色文本中打印的字符

关于使用 ANSI Escape 在ANSI Color Specific RGB Sequence Bash 输出 RGB 彩色文本的问题可能已得到解答

如果您认为不正确,请编辑它,那么我将接受修改

【讨论】:

【参考方案9】:

我不久前也遇到过这个问题,在 Windows 10 上使用 GCC。我必须设置以下注册表项才能使其工作。 [HKEY_CURRENT_USER\控制台] "VirtualTerminalLevel"=dword:00000001

【讨论】:

以上是关于如何使用 ANSI Escape 代码在控制台上输出彩色文本的主要内容,如果未能解决你的问题,请参考以下文章

修复 Linux / Unix / OS X / BSD 系统控制台上的显示乱码 | Linux 中国

如何使用 Javascript 在 Chrome 浏览器控制台上为背景着色

如何去掉控制台上输出的这些日志

如何将打印在控制台上的值存储为矢量?

如何更新在谷歌播放控制台上发布的 Java 应用程序以颤振应用程序

在 Android 开发者控制台上重用扩展文件