本文记录的是在Windows中使用C语言自定义一个可以打印彩色文字的printf函数,函数原型如下:

int colorful_printf(WORD color, const char* format, ...);

形参color接收设定的颜色,形参format是printf函数的格式字符串,后面的不确定个数的参数是printf函数的格式输出符对应的待打印项。也就是将传给printf函数的实参原封不动的传过来,再按照参数color指定的颜色进行打印。

要实现这个功能,需要预先掌握如下几方面的知识:

1、在Windows中,实现彩色打印用的是Windows的API函数SetConsoleTextAttribute,这部分知识请参考:

https://baike.baidu.com/item/SetConsoleTextAttribute/570121?fr=aladdin

https://baike.baidu.com/item/GetStdHandle/6909878?fr=aladdin

https://www.jb51.net/article/207562.htm

2、不确定个数的参数的处理,需要使用va_list,这部分知识请参考:

https://baike.baidu.com/item/va_list/8573665?fr=aladdin

https://blog.csdn.net/ZKR_HN/article/details/99558135

3、vsprintf函数,这部分知识请参考:

https://www.runoob.com/cprogramming/c-function-vsprintf.html

掌握了以上的知识后,就可以动手实现我们的函数了。比较简单,直接上代码

#pragma warning(disable:4996)
#include <Windows.h>
#include <stdio.h>
#include <stdarg.h>
#define BLUE (FOREGROUND_INTENSITY | FOREGROUND_BLUE)
#define GREEN (FOREGROUND_INTENSITY | FOREGROUND_GREEN)
#define RED (FOREGROUND_INTENSITY | FOREGROUND_RED)
#define CYAN (FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_GREEN)
#define PURPLE (FOREGROUND_INTENSITY | FOREGROUND_BLUE | FOREGROUND_RED)
#define YELLOW (FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED)
#define WHITEBGBLACKFONT ((BACKGROUND_INTENSITY | (BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED)) | (FOREGROUND_INTENSITY | !(FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)))
#define DEFAULT (FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED)int main(void)
{int colorful_printf(WORD color, const char* format, ...);colorful_printf(RED, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(GREEN, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(BLUE, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(CYAN, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(PURPLE, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(YELLOW, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");colorful_printf(WHITEBGBLACKFONT, "%d年北京冬奥会的口号是:%s\n", 2022, "一起向未来!");return 0;
}/// <summary>
/// 彩色打印
/// </summary>
/// <param name="color">预期的颜色</param>
/// <param name="format">要打印的格式化字符串</param>
/// <param name="">格式化输出的变量</param>
/// <returns>打印的字符个数(单个汉字或中文标点算两个字符)</returns>
int colorful_printf(WORD color, const char* format, ...)
{char str[256];// 要输出的字符串va_list ap;// 指向参数的指针va_start(ap, format);// 初始化指向参数的指针HANDLE consolehwnd = GetStdHandle(STD_OUTPUT_HANDLE);// 输出窗口的句柄SetConsoleTextAttribute(consolehwnd, color);// 改为使用预期的颜色输出// 按预期的颜色输出int ret = vsprintf(str, format, ap);printf("%s", str);SetConsoleTextAttribute(consolehwnd, DEFAULT);// 恢复默认效果va_end(ap);// 结束可变参数的获取return ret;
}

打印的效果:

这里记录几个技术要点:

1、要输出的字符串放在字符数组str中,一定要确保数组的长度足以容纳要打印的字符串,否则打印的时候会崩溃。

2、在这里我自定义了一些宏,全部使用了高亮效果,颜色组合的结果是百度查的,如果不够准确还请见谅。宏定义写的比较复杂,实际上完全可以用实际的数值来定义。比如宏DEFAULT,是命令行窗口的默认输出效果,完全可以写成:

#define DEFAULT     0x0007

3、colorful_printf函数的返回值实际上就是vsprintf函数的返回值,表示打印的字符的个数。一个汉字或中文标点算两个字符。

4、在单线程程序中,不会有什么问题。在多线程程序中,如果线程A使用colorful_printf函数进行输出,在内部调用SetConsoleTextAttribute()设置颜色之后,如果线程B恰好在此时进行打印,就会按照线程A中设置的颜色来打印了,这可能不是我们想要的效果。用这个程序无法完全规避这个问题,因为不同的线程都是往一个窗口(就是SetConsoleTextAttribute()的参数hConsoleOutput标识的窗口)中打印。因此只能尽可能地缩短带颜色打印的时间,就是说,调用SetConsoleTextAttribute()设置颜色之后,马上调用vsprintf()和printf()打印,然后再马上调用SetConsoleTextAttribute()恢复为默认效果。如果哪位大神知道适用于多线程,严格区分不同线程的打印颜色的方案,也欢迎指教。

Windows中使用C语言实现打印彩色文字到命令行窗口相关推荐

  1. VS中让console程序不显示(隐藏)命令行窗口

    为了让Visual Studio编译的console程序运行时不显示命令行窗口,需要在main.cpp文件中添加以下代码: #pragma comment( linker, "/subsys ...

  2. Go语言实践[回顾]教程03--Go语言的编译与运行的命令行

    Go语言实践[回顾]教程03--Go语言的编译与运行的命令行 Go语言是编译型静态语言 如何编译Go语言的源文件 如何执行(运行)编译后的文件 开发中如何编译后立即执行 总结 Go语言是编译型静态语言 ...

  3. Windows小技巧 -- 命令行窗口打开指定目录的资源管理器

    文章目录 方法一 explorer 命令快速打开指定目录的资源管理器 方法二 start 命令快速打开指定目录的资源管理器 start 命令小记 打开系统应用 打开新的命令行窗口 打开命令行窗口并执行 ...

  4. python在cmd中打印彩色文字

    版权声明:此文首发于我的个人站python在cmd中打印彩色文字,转载请注明出处. 百度来的 颜色值不太准确,下面的是亲测修改的: 单独写了一个文件 printColor.py,使用的时候只要作为模块 ...

  5. 按窗口文件php代码,在Windows命令行窗口中输入并运行PHP代码片段(不需要php文件)的方法...

    有时候只是简单的为了测试某个php函数的效果,以前总是需要建一个php文件,复制这个文件的路径,再通过web访问或者用php命令执行这个php文件. 一直想要怎么才能不用创建文件,才能直接执行PHP代 ...

  6. dos c语言显示符号图案,在DOS命令行窗口中显示出用各种字符拼凑出来的各种图案的实现方法,如本人头像...

    注:文中例子是本人刚学C++编程语言的时候制作的,实现方法很简单,主要使用for循环语句,无需什么复杂烧脑的算法. 由于经常看到各种符号拼成的图案,感觉很有意思,所以自己也弄了个,纯属好玩. (作品- ...

  7. Node.JS基础知识之命令行窗口(Windows 的命令行窗口)

    dir : 显示当前目录下的所有文件 cd 目录名 :进入 指定的 目录下 . :标识当前目录 . . :表示上一级目录 md 目录名:新建一个文件夹 rd 目录名:删除一个文件夹 环境变量:Wind ...

  8. MySQL数据库安装-Windows10为例【超级详细安装过程(每一步的截图)、检测安装是否成功、登录数据库并查看版本号、将MySQL添加到环境变量中、在命令行窗口操作数据库】

    哈哈,这是在哔哩哔哩网站上 看的 MySQL安装步骤. 我安装的时候,截截图,希望对大家 有所帮助. 链接:https://pan.baidu.com/s/1fKFQCVHMQOmbg84UyGrKB ...

  9. Windows命令行窗口 - DOS 指令

    这里写目录标题 Windows-cmd命令 rd \ /s/q 删除根目录下的所有文件 rd . /s/q 删除当前目录的所有文件:q 无提示 /s 子文件的内容 dir 查看当前目录下的文件和文本 ...

最新文章

  1. (接口)让僵冷的翅膀飞起来---从实例谈OOP、工厂模式和重构
  2. MLPclassifier,MLP 多层感知器的的缩写(Multi-layer Perceptron)
  3. IPV4报头格式详解
  4. Spring:SpringMVC一例
  5. wamp配置多少站点
  6. 【干货】嘿,产品经理 ,这些技术是一定要懂的
  7. vim 自定义命令 自定义快捷键(转)
  8. android Matrix图片变换处理
  9. Django从理论到实战(part16)--指定默认的参数
  10. python延时队列_超简便Python任务队列:huey
  11. 路径问题--转发、重定向、表单、超链接
  12. 佳士得于5月19日至27日以NFT形式拍卖安迪·沃霍尔作品
  13. weblogic调整多个服务启动顺序方法
  14. php fpm 报错,PHP-FPM安装报错解决
  15. oracle not like优化,oracle的like优化,对比了一下,效果确实比like好些。
  16. CMOS 集成电路设计手册 (基础篇)--学习笔记 第二章
  17. MovieLens官网数据集解释
  18. php后台管理员登录密码错误,织梦后台登陆不上提示验证码不正确1.密码明明正确的,却无法登陆后台管理...
  19. 计算机2进制、4进制、8进制、10进制、16进制、32进制计算规则
  20. 补点C#基础_022_json校验和json在线编辑器-bejson

热门文章

  1. 【MFC进阶】05文件处理CFile
  2. Mini CFA 考试练习题 Economics of International Trade
  3. 什么是线程阻塞?为什么会出现线程阻塞?
  4. 二、Git本地仓库基本操作——创建Git仓库、提交更新或删除文件
  5. 2021-08-09-ROS学习-消息创建,发布者和订阅者实现及测试
  6. OSPF之LSA详解
  7. 状态机在PLC中的应用
  8. python实现c语言编译器安卓版_c语言编译器ide下载app-c语言编译器ide软件下载v1.5.1 安卓版-2265安卓网...
  9. 20本必读的用户体验书目
  10. 音视频开发之旅(34) - 基于FFmpeg实现简单的视频解码器