eklavya's header file for coloring the console

The original article is here: http://www.cplusplus.com/articles/2ywTURfi/

I have slightly changed the code to make it tidier (shouldn't have any effect on performance)

This is color.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#ifndef COLOR_HPP_INCLUDED
#define COLOR_HPP_INCLUDED

#include <windows.h>

bool textcolorprotect=true;
/* doesn't let textcolor be the same as background color if true */

enum colors
{
	black = 0,
	dark_blue = 1,
	dark_green = 2,
	dark_aqua = 3, dark_cyan = 3,
	dark_red = 4,
	dark_purple = 5, dark_pink = 5, dark_magenta = 5,
	dark_yellow = 6,
	dark_white = 7,
	gray = 8,
	blue = 9,
	green = 10,
	aqua = 11, cyan = 11,
	red = 12,
	purple = 13, pink = 13, magenta = 13,
	yellow = 14,
	white = 15
};

inline void setcolor(colors textcolor, colors backcolor);
inline void setcolor(int textcolor, int backcolor);
int textcolor(); /* returns current text color */
int backcolor(); /* returns current background color */

#define std_con_out GetStdHandle(STD_OUTPUT_HANDLE)

int textcolor()
{
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	GetConsoleScreenBufferInfo(std_con_out, &csbi);
	int a = csbi.wAttributes;
	return a%16;
}

int backcolor()
{
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	GetConsoleScreenBufferInfo(std_con_out, &csbi);
	int a = csbi.wAttributes;
	return (a/16)%16;
}

inline void setcolor(colors textcol, colors backcol)
{setcolor(int(textcol), int(backcol));}

inline void setcolor(int textcol, int backcol)
{
	if(textcolorprotect)
	{if((textcol%16)==(backcol%16))textcol++;}

	textcol%=16; backcol%=16;
	unsigned short wAttributes= ((unsigned)backcol<<4) | (unsigned)textcol;
	SetConsoleTextAttribute(std_con_out, wAttributes);
}

#if defined(_INC_OSTREAM)||defined(_IOSTREAM_)
ostream& operator<<(ostream& os, colors c)
{os.flush();setcolor(c, backcolor()); return os;}
#endif

#if defined(_INC_ISTREAM)||defined(_IOSTREAM_)
istream& operator>>(istream& is, colors c)
{cout.flush();setcolor(c, backcolor()); return is;}
#endif

#endif // COLOR_HPP_INCLUDED 


and this is main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include "color.hpp"

int main()
{
	std::string input;
	SetConsoleTitle("Color");
	colors b = colors(backcolor());

	std::cout << red << "Hello \n";

	setcolor(red, yellow);
	std::cout << "Hello2 \n";

	setcolor(cyan, b);
	std::cout << "Hello3 \n";

	std::cout << blue << "Enter a word ";
	std::cin >> green >> input;
	std::cout << pink << "You entered " << yellow << input << "\n";

return 0;
}


So this gives the error
error: no match for 'operator>>' in 'std::cin >> (colors)10u'|


And anyway all of the lines that don't use setcolor, but set the color in this way std::cout << red << "hello"; output the number assigned to them e.g.
12hello
for the example above, instead of changing the color.

Don't blame me for changing the code slightly :D, I had the same problem with the original one.
Does anybody know how to fix this?
I guess that #if defined(_INC_OSTREAM)||defined(_IOSTREAM_) is evaluation to false.
Try to remove those directives.
Nope, that didn't work, I got the same error.

I am working in a Windows VM though (until I get a new PC :P) so maybe that causes some trouble....
Last edited on
Try using namespace std before including the header file.
That didn't work either, I got the error
main.cpp:23:9: note:   cannot convert '(colors)10u' (type 'colors') to type 'signed char*'
(it is line 23 after I added using namespace std; and it is the line cin >> green >> input;
Remove the defines and prefix with std::
1
2
3
4
5
6
7
8
9
//#if defined(_INC_OSTREAM)||defined(_IOSTREAM_)
std::ostream& operator<<(std::ostream& os, colors c)
{os.flush();setcolor(c, backcolor()); return os;}
//#endif

//#if defined(_INC_ISTREAM)||defined(_IOSTREAM_)
std::istream& operator>>(std::istream& is, colors c)
{std::cout.flush();setcolor(c, backcolor()); return is;}
//#endif 
Worked like a charm! Thank you naraku9333 :)

And eklavya sharma 2, I suggest you update your article with this fix, so other people don't complain about it...
After a double check, the defines seem to be ok for me in VS2012 (_IOSTREAM_ is defined but _INC_O/ISTREAM are not), but specifying the namespace was required.

@eklavya sharma 2
I would check (if you haven't already) if those defines are available in other implementations of iostream (mingw, clang)
I have uploaded a new article:
http://www.cplusplus.com/articles/Eyhv0pDG/

I have recently uploaded it so it may not have been approved yet. It will go live after some time.
Topic archived. No new replies allowed.