百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 博客教程 > 正文

轻松玩转windows控制台(二):彩色文字和彩色背景

connygpt 2024-10-10 05:19 8 浏览

写在前面

在上一篇文章中,详细的介绍了如何修改控制台窗口的标题,如何获取当前窗口标题,如何获取窗口的原始标题,并通过原始标题获取程序的绝对路径等代码示例。轻松玩转windows控制台(一):窗口标题

本篇文章将更加有趣,介绍如何将控制台屏幕上的文字设置各种颜色,以及文字的背景颜色也可以设置成各种色彩。

本篇只负责演示如何设置彩色文字和彩色屏幕,不负责审美。。。[憨笑]也就是说,我的文字和屏幕的配色可能会丑的逮鬼,但是没办法,我的审美只能是这样。

话不多说,进入正题。

一般的,我们将屏幕上文字的颜色,称为前景色。将文字所在的屏幕区域的颜色,称为背景色。在下面的文章中,有时可能会将文字颜色和前景色混用,将屏幕颜色和背景色混用。他们是等价的。

方法1:color命令

windows系统的DOS命令还是挺强大的,特别是现在PowerShell(类似于经典控制台)更是有点赶上Linux的Shell的感觉(臆想而已)。

color命令,就是其中的一个DOS命令。详细用法此处不展开,如果想了解所有用法,可以在控制台输入:color /? 即可,屏幕截图如下:

现在如果我们希望屏幕颜色是亮白色,文字颜色是红色,那么代码如下:

#include <stdio.h>
#include <windows.h>
int main() {
    system("color F4");
    printf("c是程序员的母语。\n");
    printf("你好,世界!\n");
    system("pause");
    return 0;
}

运行后,控制台文字和屏幕颜色如下:

如果用color命令,那么颜色只能从下面颜色列表里选择:

  • 0 :黑色
  • 1 :蓝色
  • 2: 绿色
  • 3:浅绿色
  • 4:红色
  • 5:紫色
  • 6:黄色
  • 7:白色
  • 8:灰色
  • 9:淡蓝色
  • A:淡绿色
  • B:淡浅绿
  • C:淡红色
  • D:淡紫色
  • E:淡黄色
  • F:亮白色

数字序列由2个16进制数字组成,第一个数字表示屏幕颜色,第二个数字表示文字颜色。比如F4,第一个数字F,代表屏幕是亮白色,第二个数字4代表文字颜色红色。

color命令是全局性质的,也就是说会在程序运行期间一直生效的。除非下次用clor命令重新设置颜色,而且每次必须是2个数字成对出现。

比如如下代码,可以灵活控制屏幕和文字的颜色显示:

#include <stdio.h>
#include <windows.h>
int main() {
    system("color F4");
    printf("现在显示白底还字。\n");
    system("pause");
    system("color 4F");
    printf("现在显示红底白字。\n");
    system("pause");
    return 0;
}

下面两张截图,分别演示了两次设置颜色时的效果:

这个方法最大的问题,在于颜色只能从这16个(0到F)十六进制数里选择,色彩非常单一。能不能通过RGB值,来进行调色?这样显示效果就会非常丰富。

方法2:wprintf函数

我们可以通过打印一种特定的格式字符来控制屏幕和文字的颜色显示。比如需要蓝底黄字的显示效果,那么下面这段代码就可以实现:

#include <stdio.h>
#include <Windows.h>
#include <wchar.h>
//wprintf函数的头文件:wchar.h
int main(){
    HANDLE hd;
    hd = GetStdHandle(STD_OUTPUT_HANDLE);
    if(hd == INVALID_HANDLE_VALUE)
        return GetLastError();
    DWORD dm = 0;
    if(!GetConsoleMode( hd, &dm))
        return GetLastError();
    dm |= 0x0004;
    if(!SetConsoleMode( hd, dm))
        return GetLastError();
    int r1,g1,b1,r2,g2,b2;
    //bg color,color:blue
    r1 = 0,g1 =0,b1 = 255;
    //fore color,clor:yellow
    r2 = 255,g2 = 255,b2 = 0;
    wprintf(L"\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dmHello,C language!\n",r2,g2,b2,r1,g1,b1);
    system("pause");
    return 0;
}

显示的效果如图:

我们来详细的解释下这段代码。

头文件部分,和上一篇中的代码相比,多了一个wchar.h 的头文件,下面代码中颜色的显示需要用到 wprintf函数,这个函数属于wchar.h。

在main函数的第一行代码中,GetStdHandle函数的参数STD_OUTPUT_HANDLE是一个预定义的常量,用于表示标准输出设备的句柄。

所谓标准输出设备,就是指控制台窗口。句柄我们就理解为一个唯一的标识符,类似于指向某个对象的指针,比如控制台窗口的句柄,就类似于指向这个控制台窗口的指针。

初学者学习windows编程,不能深究细节,前期多以模仿例程代码为主,这样能逐渐建立起windows编程的感觉。很多人不是因为学习难度大,而放弃了windows编程,而是细节太多,学着学着就迷失了。

除非必要,后面不展开细节,只是提一下相关知识点。

我们现在学习的是如何使用、操作当前的控制台窗口,控制台窗口我们可以启动很多个,而如何获得我们当前正在用的这个控制台窗口对象呢?

就是通过GetStdHandle函数获得,参数就是STD_OUTPUT_HANDLE。

总结一下:HANDLE hd = GetStdHandle(STD_OUTPUT_HANDLE); 就是获得当前正在使用的控制台窗体的句柄。

if(hd == INVALID_HANDLE_VALUE)
   return GetLastError();

INVALID_HANDLE_VALUE,见名知义,表示无效的句柄值,如果没有正确获取句柄值,就通过GetLastError函数输出错误原因(每一个错误代码,对应着一个错误的原因,此处不展开)

GetConsoleMode函数是获取当前控制台的模式,所谓控制台模式,暂时不用细究。

DWORD dm = 0;
if(!GetConsoleMode( hd, &dm))
	return GetLastError();
dm |= 0x0004;
if(!SetConsoleMode( hd, dm))
	return GetLastError();

这段代码就是设置控制台模式,细节暂时不展开分析,只要记住,这段代码必须要有,最好不要直接使用后面的wprintf函数,因为这段代码实际上就是对各种可能的异常现象进行了判断并做了处理。

wprintf(L"\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dmHello,C language!\n",r2,g2,b2,r1,g1,b1);

这个函数,类似于常用的printf函数。我们现在来稍微详细的讲解下。

函数第一个参数,是一个字符串,类似于printf函数,但是字符串前面一定要加上一个大写字母L。双引号中的\x1b[38;2;%d;%d;%dm,是一段完整的功能控制的格式字符串。说人话,就是通过这段代码来实现文字颜色的改变。

\x1b[...m中的...省略号里可以实现各种控制功能,以后会详细讲解,现在只解释文字颜色的改变。38表示是设置前景色。第一个%d代表的是RGB值中的R值,后面的2个%d分别是G值和B值。关于RGB值,此处不展开,大家自行了解。

如果38改成48,则是背景色的RGB值。后面的hello,C language!\n ,正常输出。这个字符串必须是英文的。如果显示中文,最简单的办法,就是用另外的printf函数输出即可。关于中文输出,上一篇已经介绍过,有很多办法,最简单的就是将当前控制台的代码页设置为UTF-8。

比如下面这样,就比较灵活。

#include <stdio.h>
#include <Windows.h>
#include <wchar.h>
int main(){
    HANDLE hd;
    hd = GetStdHandle(STD_OUTPUT_HANDLE);
    if(hd == INVALID_HANDLE_VALUE)
        return GetLastError();
    DWORD dm = 0;
    if(!GetConsoleMode( hd, &dm))
        return GetLastError();
    dm |= 0x0004;
    if(!SetConsoleMode( hd, dm))
        return GetLastError();
    int r1,g1,b1,r2,g2,b2;
    //bg color,color:blue
    r1 = 0,g1 =0,b1 = 255;
    //fore color,clor:yellow
    r2 = 255,g2 = 255,b2 = 0;
    wprintf(L"\x1b[38;2;%d;%d;%dm\x1b[48;2;%d;%d;%dm",r2,g2,b2,r1,g1,b1);
    printf("现在是蓝底黄字。\n");
    wprintf(L"\x1b[38;2;%d;%d;%dm",255,0,0);
    printf("现在是蓝底红字。\n");
    wprintf(L"\x1b[48;2;%d;%d;%dm",0,255,0);
    printf("现在是绿底红字。\n");
    wprintf(L"\x1b[48;2;%d;%d;%dm\x1b[38;2;%d;%d;%dm",255,0,255,0,255,255);
    printf("现在是颜色很丑。\n");
    system("pause");
    return 0;}

程序运行的效果如下:

这个方式和方法1的最大不同,一个是RGB值可以调增,另外就是只影响当前和以后的文字和屏幕的颜色,而color命令则是会将之前的文字和屏幕的颜色,都修改成现在的设置。

方法3:printf函数

我们不使用wchar.h里的wprintf函数,直接使用printf函数行不行?也可以。但是两者用的格式字符串有区别的。

在wpritf函数中,格式字符串里的38代表前景色,48代表背景色。而直接使用printf函数的话,也是通过格式字符串”\x1b[...m”来实现,但是细节有所不同。

其中省略号位置是颜色值,多个颜色值之间用分号间隔。比如\x1b[%d;%dm,多个参数之间用分号分割。前景色的取值何颜色如下:

  • 30: 黑
  • 31: 红
  • 32: 绿
  • 33: 黄
  • 34: 蓝
  • 35: 紫
  • 36: 深绿
  • 37: 白

背景色的取值何颜色对照如下:

  • 40:黑
  • 41:红
  • 42:绿
  • 43:黄
  • 44:蓝
  • 45:紫
  • 46:深绿
  • 47: 白

我们通过一段代码,来看下:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(){
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (hOut == INVALID_HANDLE_VALUE)
        return GetLastError();
    DWORD dwMode = 0;
    if (!GetConsoleMode(hOut, &dwMode))
        return GetLastError();
    dwMode |= 0x0004;
    if (!SetConsoleMode(hOut, dwMode))
        return GetLastError();
    printf("\x1b[%d;%dm",34,43);
    printf("蓝底黄字的彩色字体。\n");
    system("pause");
}

程序运行效果如下:

这段代码中,首先最开始的异常处理代码,不能省略,必须要有。\x1b[为控制格式符的开始,m 为控制格式符的结束,多个%d用;分割,将根据数值来判断是前景色还是背景色。如果是41-47,就是背景色。如果是31-37,就是前景色。

总 结

其实格式控制字符串功能非常强大,除了显示颜色前景色和背景色,还可以对文字实现其他更强大的功能,比如给文字添加下划线,甚至还可以移动当前光标的位置。

下一篇文章我们详细介绍通过各种格式控制符来实现一些控制台操作中的有趣功能。

相关推荐

3分钟让你的项目支持AI问答模块,完全开源!

hello,大家好,我是徐小夕。之前和大家分享了很多可视化,零代码和前端工程化的最佳实践,今天继续分享一下最近开源的Next-Admin的最新更新。最近对这个项目做了一些优化,并集成了大家比较关注...

干货|程序员的副业挂,12个平台分享

1、D2adminD2Admin是一个完全开源免费的企业中后台产品前端集成方案,使用最新的前端技术栈,小于60kb的本地首屏js加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助...

Github标星超200K,这10个可视化面板你知道几个

在Github上有很多开源免费的后台控制面板可以选择,但是哪些才是最好、最受欢迎的可视化控制面板呢?今天就和大家推荐Github上10个好看又流行的可视化面板:1.AdminLTEAdminLTE是...

开箱即用的炫酷中后台前端开源框架第二篇

#头条创作挑战赛#1、SoybeanAdmin(1)介绍:SoybeanAdmin是一个基于Vue3、Vite3、TypeScript、NaiveUI、Pinia和UnoCSS的清新优...

搭建React+AntDeign的开发环境和框架

搭建React+AntDeign的开发环境和框架随着前端技术的不断发展,React和AntDesign已经成为越来越多Web应用程序的首选开发框架。React是一个用于构建用户界面的JavaScrip...

基于.NET 5实现的开源通用权限管理平台

??大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!??今天小编推荐一款基于.NE...

StreamPark - 大数据流计算引擎

使用Docker完成StreamPark的部署??1.基于h2和docker-compose进行StreamPark部署wgethttps://raw.githubusercontent.com/a...

教你使用UmiJS框架开发React

1、什么是Umi.js?umi,中文可发音为乌米,是一个可插拔的企业级react应用框架。你可以将它简单地理解为一个专注性能的类next.js前端框架,并通过约定、自动生成和解析代码等方式来辅助...

简单在线流程图工具在用例设计中的运用

敏捷模式下,测试团队的用例逐渐简化以适应快速的发版节奏,大家很早就开始运用思维导图工具比如xmind来编写测试方法、测试点。如今不少已经不少利用开源的思维导图组件(如百度脑图...)来构建测试测试...

【开源分享】神奇的大数据实时平台框架,让Flink&amp;Spark开发更简单

这是一个神奇的框架,让Flink|Spark开发更简单,一站式大数据实时平台!他就是StreamX!什么是StreamX大数据技术如今发展的如火如荼,已经呈现百花齐放欣欣向荣的景象,实时处理流域...

聊聊规则引擎的调研及实现全过程

摘要本期主要以规则引擎业务实现为例,陈述在陌生业务前如何进行业务深入、调研、技术选型、设计及实现全过程分析,如果你对规则引擎不感冒、也可以从中了解一些抽象实现过程。诉求从硬件采集到的数据提供的形式多种...

【开源推荐】Diboot 2.0.5 发布,自动化开发助理

一、前言Diboot2.0.5版本已于近日发布,在此次发布中,我们新增了file-starter组件,完善了iam-starter组件,对core核心进行了相关优化,让devtools也支持对IAM...

微软推出Copilot Actions,使用人工智能自动执行重复性任务

IT之家11月19日消息,微软在今天举办的Ignite大会上宣布了一系列新功能,旨在进一步提升Microsoft365Copilot的智能化水平。其中最引人注目的是Copilot...

Electron 使用Selenium和WebDriver

本节我们来学习如何在Electron下使用Selenium和WebDriver。SeleniumSelenium是ThoughtWorks提供的一个强大的基于浏览器的开源自动化测试工具...

Quick &#39;n Easy Web Builder 11.1.0设计和构建功能齐全的网页的工具

一个实用而有效的应用程序,能够让您轻松构建、创建和设计个人的HTML网站。Quick'nEasyWebBuilder是一款全面且轻巧的软件,为用户提供了一种简单的方式来创建、编辑...