前言
提到在控制台输出彩色文字,大家都会想到使用“ANSI转义序列”(ESC \x1b \033 )
但自带的 cmd、Powershell 等终端并不能直接识别这样的序列,而是将其作为普通字符输出,非但没有美观效果,而且会让终端看起来很乱。
在此,本文给出了一种解决方案——虚拟终端序列。为C语言控制台程序开启该特性后,即可完美实现彩色输出。
效果图
使用之后的效果是这样的(cmd):
开工
简要介绍
虚拟终端序列是控制字符序列,可在写入输出流时控制游标移动、控制台颜色和其他操作。 在输入流上也可以接收序列,以响应输出流查询信息序列,或在设置适当模式时作为用户输入的编码。
序列的行为基于 VT100 和派生终端仿真器技术,尤其是 xterm 终端仿真器。
——摘自 Microsoft
默认情况下,这个模式是关闭的,因此需要通过代码开启。(注意 Win7 系统可能不适用)
参考代码
Step1,构建一个函数来启用虚拟终端序列特性。
新建一个 print.c ,这里面是开启特性的关键代码:
#include "print.h"
/*!
* 为传统控制台启用色彩支持
*/
DWORD enableColorful(void)
{
#if PRINT_COLORFUL
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return GetLastError();
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return GetLastError();
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return GetLastError();
}
#endif
return 0;
}
然后新建一个 print.h 用于声明上面的函数,以及设置常用颜色的宏定义:
#ifndef PRINT_H
#define PRINT_H
#include <stdio.h>
#include <windows.h>
DWORD enableColorful(void);
//* 配置 */
#define PRINT_COLORFUL 1 // 是否启用彩色
//* 颜色定义 */
#define COLOR_GRAY "\033[37m"
#define COLOR_GREEN "\033[32m"
#define COLOR_YELLOW "\033[33m"
#define COLOR_DARKGRAY "\033[30m"
#define COLOR_BLACK "\033[30m"
#define COLOR_NOCOLOR "\033[0m"
#define COLOR_DEEPBLUE "\033[34m"
#define COLOR_RED "\033[31m"
#endif // PRINT_H
Step2,在需要启用彩色的控制台中调用此函数即可。
示例都在代码里啦,注释也很丰富~
main.c :
#include "print.h"
int main()
{
enableColorful(); // 开启彩色支持
// 使用示例
printf(COLOR_GREEN "INFO: 这是一条提示信息\n" COLOR_NOCOLOR);
printf(COLOR_RED "ERROR: 这是一条错误信息\n" COLOR_NOCOLOR);
// 接下来的示例来自微软
// Try some Set Graphics Rendition (SGR) terminal escape sequences
wprintf(L"\x1b[31mThis text has a red foreground using SGR.31.\r\n");
wprintf(L"\x1b[1mThis text has a bright (bold) red foreground using SGR.1 to affect the previous color setting.\r\n");
wprintf(L"\x1b[mThis text has returned to default colors using SGR.0 implicitly.\r\n");
wprintf(L"\x1b[34;46mThis text shows the foreground and background change at the same time.\r\n");
wprintf(L"\x1b[0mThis text has returned to default colors using SGR.0 explicitly.\r\n");
wprintf(L"\x1b[31;32;33;34;35;36;101;102;103;104;105;106;107mThis text attempts to apply many colors in the same command. Note the colors are applied from left to right so only the right-most option of foreground cyan (SGR.36) and background bright white (SGR.107) is effective.\r\n");
wprintf(L"\x1b[39mThis text has restored the foreground color only.\r\n");
wprintf(L"\x1b[49mThis text has restored the background color only.\r\n");
return 0;
}
到此,新技能成功 Get √。
总体上来说,使用还是很方便而且简单的,欢迎各位小伙伴交流。
其它知识
ANSI 转义码格式
基本格式如下:
\x1b[(文字装饰);(颜色代码):
文字装饰:
颜色代码:
基本 8 色 |
基本高对比色 |
xterm 的 256色 |
30 ~ 37 |
90 ~ 97 |
0 ~ 256 |
关于更多的颜色可以参考一下 Wiki:ANSI escape code
一些值得参考的资料
-
[浅析 \x1B[1;3;31mxterm.js\x1B[0m是什么?如何在终端输出带颜色等格式的字符串](https://www.cnblogs.com/goloving/p/15015053.html)
-
Microsoft官方文档:控制台虚拟终端序列
|