C语言控制台下printf设置文字颜色和背景色以及实现简单的文字选择菜单_c printf color-程序员宅基地

技术标签: 控制台  C语言  

这里说到的两个内容差不多都可以用在控制台上运行的一些小游戏里,控制某一部分的字体颜色和背景色以达到高亮显示强调的效果,这个选择菜单就是通过方向键或者自定义按键然后进行选项的选择。
比较简单,但是挺好玩的,就随便看看吧。

修改控制台的前景色和背景色

这里直接调用系统的函数,system(“color ef”);,即可实现,这个代码就是在控制台调用color指令,可以通过在控制台运行color …或者在代码中直接插入system(“color …”);,他就会输出有关这个指令的相关信息,包括每个数字表示什么颜色。
有两点需要注意的,一点是color后面跟的数是两位十六进制,分别表示前景色和背景色,第二点需要注意的是,这里修改的是全局设置,也就是说调用一次之后,整个控制台都会发生改变,而并不是针对某一位置或者某一段字符进行设置,如果像针对某一个字符串进行设置,看下面。

printf彩色输出

是通过控制台的转义序列来实现的,这是文本模式下的系统显示功能,似乎和语言没有太大联系。转义序列是以ESC开始的,即\033ESC的十进制是27,转为八进制就是33了。
通用格式大致为ESC[{attr1};{attr2};…;{attrn}m,其中attr表示的是属性,也是属性值,通常直接就是数字表示了。在此我们进行三个常用属性的设置,主要是显示方式、字体颜色和背景色。
显示方式

  • 0(默认值)
  • 1(高亮显示,顺便加粗?不确定)
  • 2(暗淡)
  • 22(非粗体,不确定)
  • 4(下划线)
  • 5(闪烁,但是我没看出有什么效果。。)
  • 25(非闪烁)
  • 7(反显,我也没看出效果)
  • 27(非反显)
  • 8(隐藏)

字体颜色

  • 30(黑色)
  • 31(红色)
  • 32(绿色)
  • 33(黄色)
  • 34(蓝色)
  • 35(品红)
  • 36(青色)
  • 37(白色)

背景色

  • 40(黑色)
  • 41(红色)
  • 42(绿色)
  • 43(黄色)
  • 44(蓝色)
  • 45(品红)
  • 46(青色)
  • 47(白色)

大致使用的示例代码如下
printf("\033[4;31;42m 输出红色绿背景下划线字符 \033[0m");
在这里插入图片描述
这里我写了个函数可以直接拿来用,我写的比较啰嗦,你可以去把它优化一下,后面两个设置为NoneType的话就是默认显示方式而且结尾没有换行符或者回车。

#define HighLight 1
#define Underline 4
#define Spark 5
#define Contrary 7
#define Miss 8
#define NONETYPE 0
#define PTab 11
#define PEnter 12
...
void print(char *Message, char *ForeColor, char *BackgroundColor, int flag,int End) {
    
	//参数分别为输出的信息,字体颜色,背景色,显示方式和结尾标志
	char ColorArray[8][10] = {
     "black","red","green","yellow","blue","purple","deepgreen","white" };
	int ForeNum, BackgroundNum;
	for (int i = 0; i < 8; i++) {
    
		if (strcmp(ColorArray[i], ForeColor) == 0)
			ForeNum = i;
		else if (strcmp(ColorArray[i], BackgroundColor) == 0)
			BackgroundNum = i;
	}
	if (End == NONETYPE) {
    
		if (flag==NONETYPE)
			printf("\033[%d;%dm%s\033[0m",40+BackgroundNum,30+ForeNum,Message);
		else
			printf("\033[%dm\033[%d;%dm%s\033[0m",flag, 40 + BackgroundNum, 30 + ForeNum,Message);
	}
	else if (End == PTab) {
    
		if (flag == NONETYPE)
			printf("\033[%d;%dm%s\033[0m\t", 40 + BackgroundNum, 30 + ForeNum, Message);
		else
			printf("\033[%dm\033[%d;%dm%s\033[0m\t", flag, 40 + BackgroundNum, 30 + ForeNum,Message);
	}
	else if (End == PEnter) {
    
		if (flag == NONETYPE)
			printf("\033[%d;%dm%s\033[0m\n", 40 + BackgroundNum, 30 + ForeNum, Message);
		else
			printf("\033[%dm\033[%d;%dm%s\033[0m\n", flag, 40 + BackgroundNum, 30 + ForeNum,Message);
	}
}

控制台菜单选择的实现

这个的灵感是来自控制台的文字游戏,如果总是让用户去输入字符或者数字来进行选项的选择的话,肯定会有些繁琐而且不太顺手,就萌生了一个简单的菜单的制作。
在此我选择的是利用方向键进行选项的选择,横向放置的菜单,纵向当然也很容易就改了,使用getch()获取字符,这个函数的特点是,不需要回车,而且也不会有字符的回显,非常适合进行游戏的输入。
首先需要知道使用getch()函数得到的是什么,这个函数返回值可以认为是接收到字符的ascii码,但是做一个小测试就会发现,其实并不是得到的值就可以直接用,看下面

while (1) {
    
		ch = getch();
		printf("%d\t%c\n", ch,ch);
	}

其实他是有一个输入的,但是我觉得他是在我后面还多获取了一个表示结束的东西吧,所以他第二次循环的时候默认就读取了这个,ascii码值为0,如果把printf换成putchar就可以正常显示字符了,因为0不会被认为是可显示的字符。
在这里插入图片描述
因此在获取输入的时候需要进行判断其是否为0,可以使用if (ch=getch()),也可以while (ch=getch())
之后就要说一下,在读取方向键的时候,第一次并不会返回正常的值,有第地方说可能是0或者224,我这里测试是第一个返回值为-32,这也能解释当上一步使用getch()读取方向键的时候,如果输出ascii码会发现输出为?-32,因为第一个返回值为-32。需要使用两次该函数才可以成功获取到方向键,如下所示

while (1) {
    
		if (c1 = getch()) {
    
			c2 = getch();
		}
		printf("%d\t%d\n", c1, c2);
	}

测试数据分别是a、A、↑、↓、←、→、E,可以发现,字符的第二个返回值都默认是0,方向键的第一个返回值都是-32,因此可以获取两次,根据两个返回值的不同判断读取的是字符还是方向键。
在这里插入图片描述
这是已经实现的简单的菜单选择方式,别忘了#include <Windows.h>,这里实现了gotoxy()

#include <Windows.h>
...
#define UpKey 35
#define DownKey 43
#define LeftKey 38
#define RightKey 40
...
void gotoxy(int x, int y) {
    
	COORD pos = {
     x,y };
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
	SetConsoleCursorPosition(hOut, pos);
}
int main() {
    
	char str[5][10] = {
     "菜单1","菜单2","菜单3","菜单4","菜单5" };
	int Number = 5;
	int Chosen = 0;
	char c1 = 'a', c2 = 'a',ch='a';
	printf("请选择:");
	while (ch != 'q') {
    
		gotoxy(10, 0);
		for (int i = 0; i < Number; i++) {
    
			if (Chosen == i)
				print(str[i], "white", "black", Underline, PTab);
			else
				printf("%s\t", str[i]);
		}
		if (c1 = getch()) {
    
			c2 = getch();
		}
		//判断按键
		if (c1 > 0)
			ch = c1;
		else
			ch = c2-37;
		switch (ch) {
    
			case UpKey:printf("上\n"); break;
			case DownKey:printf("下\n"); break;
			case LeftKey:
				if (Chosen > 0)
					Chosen--;
				break;
			case RightKey:
				if (Chosen < Number-1)
					Chosen++;
				break;
			default:printf("字符:%c\n", ch); break;
		}
	}
	return 0;
}

效果如下图所示
在这里插入图片描述
在这里插入图片描述
实现方式就是设置一个选择标记,每次利用gotoxy定位到文本位置,进行输出,即覆盖了原来的输出,根据选择标记对当前选中的选项进行高亮标记,我这里用的是下划线,也可以改成利用不同的字体颜色或者背景色进行高亮,比较简单。
今天就先到这吧,有点晚了,等改天再写写利用前缀显示的选择菜单的样子。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41037945/article/details/92759586

智能推荐

c# 调用c++ lib静态库_c#调用lib-程序员宅基地

文章浏览阅读2w次,点赞7次,收藏51次。四个步骤1.创建C++ Win32项目动态库dll 2.在Win32项目动态库中添加 外部依赖项 lib头文件和lib库3.导出C接口4.c#调用c++动态库开始你的表演...①创建一个空白的解决方案,在解决方案中添加 Visual C++ , Win32 项目空白解决方案的创建:添加Visual C++ , Win32 项目这......_c#调用lib

deepin/ubuntu安装苹方字体-程序员宅基地

文章浏览阅读4.6k次。苹方字体是苹果系统上的黑体,挺好看的。注重颜值的网站都会使用,例如知乎:font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, W..._ubuntu pingfang

html表单常见操作汇总_html表单的处理程序有那些-程序员宅基地

文章浏览阅读159次。表单表单概述表单标签表单域按钮控件demo表单标签表单标签基本语法结构<form action="处理数据程序的url地址“ method=”get|post“ name="表单名称”></form><!--action,当提交表单时,向何处发送表单中的数据,地址可以是相对地址也可以是绝对地址--><!--method将表单中的数据传送给服务器处理,get方式直接显示在url地址中,数据可以被缓存,且长度有限制;而post方式数据隐藏传输,_html表单的处理程序有那些

PHP设置谷歌验证器(Google Authenticator)实现操作二步验证_php otp 验证器-程序员宅基地

文章浏览阅读1.2k次。使用说明:开启Google的登陆二步验证(即Google Authenticator服务)后用户登陆时需要输入额外由手机客户端生成的一次性密码。实现Google Authenticator功能需要服务器端和客户端的支持。服务器端负责密钥的生成、验证一次性密码是否正确。客户端记录密钥后生成一次性密码。下载谷歌验证类库文件放到项目合适位置(我这边放在项目Vender下面)https://github.com/PHPGangsta/GoogleAuthenticatorPHP代码示例://引入谷_php otp 验证器

【Python】matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距-程序员宅基地

文章浏览阅读4.3k次,点赞5次,收藏11次。matplotlib.plot画图横坐标混乱及间隔处理_matplotlib更改横轴间距

docker — 容器存储_docker 保存容器-程序员宅基地

文章浏览阅读2.2k次。①Storage driver 处理各镜像层及容器层的处理细节,实现了多层数据的堆叠,为用户 提供了多层数据合并后的统一视图②所有 Storage driver 都使用可堆叠图像层和写时复制(CoW)策略③docker info 命令可查看当系统上的 storage driver主要用于测试目的,不建议用于生成环境。_docker 保存容器

随便推点

网络拓扑结构_网络拓扑csdn-程序员宅基地

文章浏览阅读834次,点赞27次,收藏13次。网络拓扑结构是指计算机网络中各组件(如计算机、服务器、打印机、路由器、交换机等设备)及其连接线路在物理布局或逻辑构型上的排列形式。这种布局不仅描述了设备间的实际物理连接方式,也决定了数据在网络中流动的路径和方式。不同的网络拓扑结构影响着网络的性能、可靠性、可扩展性及管理维护的难易程度。_网络拓扑csdn

JS重写Date函数,兼容IOS系统_date.prototype 将所有 ios-程序员宅基地

文章浏览阅读1.8k次,点赞5次,收藏8次。IOS系统Date的坑要创建一个指定时间的new Date对象时,通常的做法是:new Date("2020-09-21 11:11:00")这行代码在 PC 端和安卓端都是正常的,而在 iOS 端则会提示 Invalid Date 无效日期。在IOS年月日中间的横岗许换成斜杠,也就是new Date("2020/09/21 11:11:00")通常为了兼容IOS的这个坑,需要做一些额外的特殊处理,笔者在开发的时候经常会忘了兼容IOS系统。所以就想试着重写Date函数,一劳永逸,避免每次ne_date.prototype 将所有 ios

如何将EXCEL表导入plsql数据库中-程序员宅基地

文章浏览阅读5.3k次。方法一:用PLSQL Developer工具。 1 在PLSQL Developer的sql window里输入select * from test for update; 2 按F8执行 3 打开锁, 再按一下加号. 鼠标点到第一列的列头,使全列成选中状态,然后粘贴,最后commit提交即可。(前提..._excel导入pl/sql

Git常用命令速查手册-程序员宅基地

文章浏览阅读83次。Git常用命令速查手册1、初始化仓库git init2、将文件添加到仓库git add 文件名 # 将工作区的某个文件添加到暂存区 git add -u # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,不处理untracked的文件git add -A # 添加所有被tracked文件中被修改或删除的文件信息到暂存区,包括untracked的文件...

分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120-程序员宅基地

文章浏览阅读202次。分享119个ASP.NET源码总有一个是你想要的_千博二手车源码v2023 build 1120

【C++缺省函数】 空类默认产生的6个类成员函数_空类默认产生哪些类成员函数-程序员宅基地

文章浏览阅读1.8k次。版权声明:转载请注明出处 http://blog.csdn.net/irean_lau。目录(?)[+]1、缺省构造函数。2、缺省拷贝构造函数。3、 缺省析构函数。4、缺省赋值运算符。5、缺省取址运算符。6、 缺省取址运算符 const。[cpp] view plain copy_空类默认产生哪些类成员函数

推荐文章

热门文章

相关标签