如何使用 ANSI 转义码在 C 和 C++ 中输出彩色文本?

发布于 2024-12-04 15:35:09 字数 735 浏览 9 评论 0原文

我在此处阅读了有关 ANSI-C 转义码的信息。尝试在 C/C++ printf/std::cout 中使用它来对输出到控制台的文本进行着色,但没有成功。

我的尝试:

#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 中给出了编译错误。哪个编译器有这个功能?有详细信息吗?

I read about ANSI-C escape codes here. Tried to use it in C/C++ printf/std::cout to colorize the text outputted to console, but without success.

My attempt:

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

How can I use these escape codes to output colored text to console?

Am I missing something?

Also, I remember that in some C++ code I saw a call to this function

textcolor(10);

But it gives compilation errors in g++ and in Visual Studio. Which compiler had this function available? Any details?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

聊慰 2024-12-11 15:35:09

恐怕您忘记了 ESC 字符:

#include <cstdio>

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

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

I'm afraid you forgot the ESC character:

#include <cstdio>

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

Unfortunately it will only work on consoles that support ANSI escape sequences (like a linux console using bash, or old Windows consoles that used ansi.sys)

Oo萌小芽oO 2024-12-11 15:35:09

我不久前创建了一个非常简单的文本管理库,它是多平台的,它使用本机 API 调用适用于其余平台的 Windows 和 ANSI 转义序列。它有完整的文档,您还可以浏览源代码。

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

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

希望这有帮助。

I created a very simple text-management library some time ago, being multiplatform, it uses native API calls for Windows and ANSI escape sequences for the rest of the platforms. It is fully documented and you can also browse the source code.

About your specific question, I think you are missing some codes. For example, in order to change the color of text, you should use something like:

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

Hope this helps.

許願樹丅啲祈禱 2024-12-11 15:35:09

在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://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences][ 1]

under windows 10 one can use VT100 style by activating the VT100 mode in the current console :

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

see msdn page : [https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences][1]

蛮可爱 2024-12-11 15:35:09

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

2016 年,微软发布了 Windows 10 Version 1511 更新,意外地实现了对 ANSI 转义序列的支持。这一更改旨在补充适用于 Linux 的 Windows 子系统,为命令提示符使用的 Windows 控制台主机添加对类 Unix 系统的基于终端的软件所使用的字符转义码的支持。这不是默认行为,必须通过 SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING)

使用 Win32 API 以编程方式启用

A note to anybody reading this post: https://en.wikipedia.org/wiki/ANSI_escape_code#DOS_and_Windows

In 2016, Microsoft released the Windows 10 Version 1511 update which unexpectedly implemented support for ANSI escape sequences. The change was designed to complement the Windows Subsystem for Linux, adding to the Windows Console Host used by Command Prompt support for character escape codes used by terminal-based software for Unix-like systems. This is not the default behavior and must be enabled programmatically with the Win32 API via SetConsoleMode(handle, ENABLE_VIRTUAL_TERMINAL_PROCESSING)

ANSI 转义码使用 ansi.sys 设备驱动程序在 DOS 上运行。它们不适用于 Windows XP 或更高版本。您需要使用 控制台 API SetConsoleTextAttribute()

textcolor 在 borland Turbo C++ 编译器中可用。

ANSI escape codes worked on DOS using the ansi.sys device driver. They won't work windows xp or higher. You need to use the console API SetConsoleTextAttribute()

textcolor was available in the borland turbo c++ compiler.

假情假意假温柔 2024-12-11 15:35:09

Windows 10 支持 VT100 上的 ANSI 转义序列以及具有 256 色扩展的派生终端仿真器技术。说明和示例位于页面控制台虚拟终端序列< /a>.

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();

Windows 10 supports ANSI Escape Sequences on the VT100 and derived terminal emulator technologies with 256 color extension. Description and examples are on the page 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();
-小熊_ 2024-12-11 15:35:09

Windows 不支持 ANSI 格式代码。

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

ANSI formatting codes aren't supported in windows.

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

秋叶绚丽 2024-12-11 15:35:09

这适用于支持 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 是要以彩色打印的字符text

这可能是关于使用 ANSI Escape 在 ANSI 颜色特定 RGB 序列 Bash

如果您认为这不正确,只需编辑然后我会接受修改

This will work in any OS that support ANSI escape sequence

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

Note:

char r is your red in RGB

char g is your green in RGB

char b is your blue in RGB

char char is you character to print in colored text

This may be been answered about using ANSI Escape to output RGB colored text at ANSI Color Specific RGB Sequence Bash

If you think that not true just edit it then i will accept the modification

筑梦 2024-12-11 15:35:09

着色 ANSI 转义码使用选择图形呈现 (SGR) 序列,其中格式为 CSI n m,其中 CSI(代表控制序列引入器)序列只是转义字符后跟一个左方括号,n 是一些参数,m 是文字“m”字符。

棘手的部分实际上只是获取 C++ 字符串文字中的转义字符。你可以看到 https://en.cppreference.com/w/cpp/language/escape 有关 C++ 中字符串转义的信息。 TL;DR 是您可以使用八进制形式,如 \nnn,或十六进制形式,如 \xn...ASCII 中的 ESC 字符 的值为 27,八进制为 33,十六进制为,是 1b。因此,您可以使用 "\033[...m""\x1b[...m"

例如:(

"\033[31mred \033[33myellow \033[32mgreen \033[36mcyan \033[34mblue \033[35mmagenta"
"\x1b[31mred \x1b[33myellow \x1b[32mgreen \x1b[36mcyan \x1b[34mblue \x1b[35mmagenta"

有趣的事实:Bash 对字符串使用类似的转义序列,因此您可以在 Bash shell 中 echo -e 上面的字符串文字,它也可以工作)

对于 C++20,我使用我的一个项目的头文件中的以下代码片段用于定义一些更具可读性的常量:

#include <string_view>

struct SgrPair final {
    std::string_view on;
    std::string_view off;
};
#if USE_ANSI_ESC
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {(ON_STR)}, .off {(OFF_STR)} };
#else
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {""}, .off {""} };
#endif

SGR(dim, "\033[2m",  "\033[22m")
SGR(red, "\033[31m", "\033[39m")

#undef SGR

在上面的代码片段中,进行编译的用户可以选择是否将 USE_ANSI_ESC 宏定义为真值。

另请参阅 ANSI 颜色转义序列列表https://www.ecma-international.org/publications-and-standards/standards/ecma-48/

Windows 痛苦和苦难乐趣

如果你的程序被打印到 Windows 控制台(如 cmd),你需要在程序中编写一些内容以在该控制台中启用 ANSI 转义码(请参阅 https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences):

#ifdef _WIN32
#include <windows.h>
#endif

int main() {
    // ...
    #ifdef _WIN32
    DWORD con_mode;
    GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &con_mode);
    con_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), con_mode);
    // ...
}

其他答案已经涉及到这一点,但我添加了一些预处理器包装以使在非 Windows 平台上编译更容易,无需更改代码。

什么是“textcolor”

这是一个 Turbo C/C++ 编译器函数。请参阅Turbo C/C++ 编译器 2.0 文档的第 384 页。另请参阅:conio.h 不包含 textcolor()?

Colorization ANSI escape codes use Select Graphic Rendition (SGR) sequences, which are of the form CSI n m, where a CSI (which stands for Control Sequence Introducer) sequence is just the escape character followed by an opening square brace, n is some parameter, and m is the literal "m" character.

The tricky part is really just getting the escape character in a C++ string literal. You can see https://en.cppreference.com/w/cpp/language/escape for info about string escapes in C++. The TL;DR is that you can use octal form like \nnn, or hexadecimal form like \xn.... The ESC character in ASCII is value 27, which in octal is 33, and in hexadecimal, is 1b. So you can either use "\033[...m" or "\x1b[...m".

For example:

"\033[31mred \033[33myellow \033[32mgreen \033[36mcyan \033[34mblue \033[35mmagenta"
"\x1b[31mred \x1b[33myellow \x1b[32mgreen \x1b[36mcyan \x1b[34mblue \x1b[35mmagenta"

(fun fact: Bash uses similar escape sequences for strings, so you can echo -e the above string literals in a Bash shell and it will also work)

For C++20, I use the following snippet in a header file in one of my projects to define some more readable constants:

#include <string_view>

struct SgrPair final {
    std::string_view on;
    std::string_view off;
};
#if USE_ANSI_ESC
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {(ON_STR)}, .off {(OFF_STR)} };
#else
#define SGR(NAME, ON_STR, OFF_STR) inline constexpr SgrPair NAME { .on {""}, .off {""} };
#endif

SGR(dim, "\033[2m",  "\033[22m")
SGR(red, "\033[31m", "\033[39m")

#undef SGR

In the above snippet, the user doing the compilation can choose whether or not to define the USE_ANSI_ESC macro to a truthy value.

See also List of ANSI color escape sequences and https://www.ecma-international.org/publications-and-standards/standards/ecma-48/.

Windows pain and suffering fun

If your program is printed to a Windows console like cmd, you need to write something in your program to enable ANSI escape codes in that console (see https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences):

#ifdef _WIN32
#include <windows.h>
#endif

int main() {
    // ...
    #ifdef _WIN32
    DWORD con_mode;
    GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &con_mode);
    con_mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), con_mode);
    // ...
}

The other answers already touched on this, but I added some preprocessor wrapping to make it easier to compile on non-Windows platforms without changing the code.

What "textcolor" is

It's a Turbo C/C++ Compiler function. See page 384 of the Turbo C/C++ Compiler 2.0 docs. See also: conio.h doesn't contain textcolor()?.

假面具 2024-12-11 15:35:09

不久前,我在 Windows 10 上使用 GCC 时也遇到了这个问题。我必须设置以下注册表项才能使其正常工作。 [HKEY_CURRENT_USER\控制台]
“虚拟终端级别”=dword:00000001

I had this problem a while ago, too, using GCC on Windows 10. I had to set the following registry key to get it to work. [HKEY_CURRENT_USER\Console]
"VirtualTerminalLevel"=dword:00000001

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文