C++ Demo 002 : 让 STL 中的 cout 输出彩色的文字
缘起:
这是一个从 CodeProject 上看到的小程序,很有意思。原文里面没有任何对代码的解释和说明,这里摘过来,做个笔记。
程序的原作者 :Vincent Godin
题目:
写一个程序,让 STL 中的 cout 输出彩色的文字到显示器上。
环境:
Windows XP Professional sp3 下面用 GNU GCC 的编译器编译,它支持标准C++。推荐使用!*^_^*
实验步骤:
1,新建一个文本文件,命名 "console_color.h" 。
2,粘贴一下代码到此 .h 文件中。
// ConsoleColor.h
#ifndef _CONSOLE_COLOR_H_
#define _CONSOLE_COLOR_H_
#include <iostream>
#include <windows.h>
inline std::ostream& blue(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}
inline std::ostream& red(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED|FOREGROUND_INTENSITY);
return s;
}
inline std::ostream& green(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}
inline std::ostream& yellow(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY);
return s;
}
inline std::ostream& white(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,
FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);
return s;
}
struct color {
color(WORD attribute):m_color(attribute){};
WORD m_color;
};
template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>&
operator<<(std::basic_ostream<_Elem,_Traits>& i, const color& c)
{
HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,c.m_color);
return i;
}
#endif
// Copyleft Vincent Godin
3,另外,新建一个文本文件,命名"console_color_test.cpp"
4,粘贴一下代码到此 .cpp 文件中。
#include "console_color.h"
int main()
{
std::cout << green << "绿色的文本哦。" << red << "这个是红的吧!"
<< white << std::endl;
std::cout << color(FOREGROUND_RED|FOREGROUND_GREEN)
<< "This text has a really exiting color ! -- edited by Vincent"
<< white << std::endl;
return 0;
}
5,利用 GCC 编译这个文件。
g++ console_color_test.cpp -o main
6,在控制台输入 main 运行程序,看看效果吧。有点意思。
讨论:
//核心代码段,举一个函数说一下,其他的函数都是换了参数而已。
inline std::ostream& blue(std::ostream &s)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout, FOREGROUND_BLUE
|FOREGROUND_GREEN|FOREGROUND_INTENSITY);
return s;
}
整个函数就是定义了一个用于输出流的控制符,看过 std::endl 的定义吗,呵呵,就是模仿它了。
这里面用到了两个函数,GetStdHandle 和 SetConsoleTextAttribute 。
HANDLE GetStdHandle( DWORD nStdHandle);
这个函数用来获取标准输入、输出以及标准错误设备的句柄。
BOOL SetConsoleTextAttribute( HANDLE hConsoleOutput, WORD wAttributes);
用来设置控制台文本的属性,更多的内容查看 MSDN 吧。我也懒得翻译了,都非常容易明白。
color 结构体不说了,非常简单。
剩下来的,就是这个重载的 << 操作符。仔细看一下,Vincent 这哥们用了模板来实现,第一个参数是一个输出流的对象,第二个参数就是个 color 结构体,用来传入结构体中放入的颜色属性。*^_^*
template <class _Elem, class _Traits>
std::basic_ostream<_Elem,_Traits>&
operator<<(std::basic_ostream<_Elem,_Traits>& i, const color& c)
{
HANDLE hStdout=GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hStdout,c.m_color);
return i;
}
总结:
本文是对 Win32 API 关于 Console 这一块的一个小应用,还是有点意思的。至少,把这个封装成 lib 后,你可以让你的 Console 变得更可爱一点。不再是默认的黑白配了。-_-!
参考资料:
[1] MSDN Console Functions (Windows) : http://msdn.microsoft.com/en-us/library/ms682073%28v=VS.85%29.aspx
[2] CodeProject Command line processing (Add color to your std::cout) : http://www.codeproject.com/KB/cpp/cout_color.aspx