使用 C/C++,如何以彩色打印到标准输出,但前提是终端支持它?

Posted

技术标签:

【中文标题】使用 C/C++,如何以彩色打印到标准输出,但前提是终端支持它?【英文标题】:Using C/C++, how do you print to stdout in color, but only if the terminal supports it? 【发布时间】:2012-10-01 09:13:57 【问题描述】:

我有一个程序可以将内容记录到STDOUT

这些日志条目具有关联的“日志级别”(调试、警告、信息等),我想让用户能够根据日志级别为该输出着色。

确定STDOUT 是否连接到支持颜色的终端的方法是什么? 那么我怎样才能用颜色输出我的文本呢?

我正在寻找仅涉及 C 或 C++ 调用的解决方案。我猜curses(或ncurses)可以缓解这种情况,但我想避免使用它来将我的依赖关系降至最低。

【问题讨论】:

这是同一个问题吗? ***.com/questions/2353430/… 您不想手动阅读 terminfo 数据库。不,你没有。 见***.com/questions/2465425/… 对于潜在的“完全重复”选民:建议的重复回答确定STDOUT 是否具有颜色能力的问题。 @DavidHammen:Git 实际上是这样做的:它检测是否将输出发送到终端,以及用户是否需要颜色,并且只有在这两个条件都匹配时才输出它们。 【参考方案1】:

可能最简单的检查方法是:

isatty(fileno(STDOUT))

如果您的标准输出被发送到任何类型的终端,这将返回1。实际上,任何终端都将支持或忽略 VT100 颜色代码;检查 terminfo 是不必要的,除非您希望输出到某些非常不寻常的硬件终端。 (其中大部分已经几十年没有制造了。)

要输出颜色,请使用(扩展的)SGR 序列:

"\x1b[%dm"

其中%d 是常用支持颜色的以下值之一:

0: reset colors/style
1: bold
4: underline
30 - 37: black, red, green, yellow, blue, magenta, cyan, and white text
40 - 47: black, red, green, yellow, blue, magenta, cyan, and white background

还有更多的值,但这些是得到最广泛支持的值。同样,对于这些控制代码来说,检查 terminfo 基本上是不必要的,因为每个值得一提的软件终端都会支持(或忽略)它们。

如果您需要一次更改多个属性,您可以一次指定它们,用分号分隔。例如,以下序列将在绿色背景上用粗体洋红色文本灼伤您的眼球:

"\x1b[1;35;42m"

【讨论】:

这是 ANSI,而不是 VT100 代码。或者如果你想准确的话,也许是 ISO/IEC 6429 代码。请注意"\x1b[" == "\033[" == CSI。 en.wikipedia.org/wiki/ANSI_escape_code#CSI_codes 有一个很好的列表,以及可移植性和其他有用的信息。 备案:Xcode(OSX 的标准 IDE)内置控制台不支持(也不忽略)ANSI 颜色序列(它试图打印它们,导致无法读取的垃圾)。实际上,我真的很喜欢一个可以检查颜色支持的 sn-p。

以上是关于使用 C/C++,如何以彩色打印到标准输出,但前提是终端支持它?的主要内容,如果未能解决你的问题,请参考以下文章

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

有啥方法可以用 NSLog 进行彩色打印?

如何以彩色打印到控制台? [复制]

如何将彩色文本输出到 Linux 终端?

记录器配置以记录到文件并打印到标准输出

启动另一个程序并充当其标准输出的程序[重复]