Reputation:
I tried using system("color 24");
but that didn't change the color in the prompt. So after more Googling I saw SetConsoleTextAttribute
and wrote the below code.
This results in both stdout
and stderr
both getting colored red instead of stdout
being green and stderr
being red.
How do I solve this? My prompt is also now red but I don't care about that since I know how to fix it.
Should work in Windows 7. At the moment I'm building this from the prompt (using VS 2010 cl) and running it in a regular cmd
prompt
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv)
{
int i;
unsigned long totalTime=0;
HANDLE hConsoleOut; //handle to the console
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsoleOut, FOREGROUND_GREEN);
HANDLE hConsoleErr;
hConsoleErr = GetStdHandle(STD_ERROR_HANDLE);
SetConsoleTextAttribute(hConsoleErr, FOREGROUND_RED);
fprintf(stdout, "%s\n", "out");
fprintf(stderr, "%s\n", "err");
return 0;
}
Upvotes: 7
Views: 5234
Reputation: 94
According to the MSDN GetStdHandle()
documentation, the function will return handles to the same active console screen buffer. So setting attributes using these handles will always change the same buffer. Because of this you have to specify the color right before you right to the output device:
/* ... */
HANDLE hConsoleOut; //handle to the console
HANDLE hConsoleErr;
hConsoleErr = GetStdHandle(STD_ERROR_HANDLE);
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleTextAttribute(hConsoleOut, FOREGROUND_GREEN);
fprintf(stdout, "%s\n", "out");
SetConsoleTextAttribute(hConsoleErr, FOREGROUND_RED);
fprintf(stderr, "%s\n", "err");
return 0;
Upvotes: 7
Reputation: 131789
The handle for error and normal console output are the same. Or more like, they point to the same console window. When you change the console color, it applies to all text written after that, so you'd need to change the color directly before the output. If you don't want to do that for every text you output, pack the calls into a seperate function:
#include <windows.h>
#include <stdio.h>
// global vars (better pack it in a class)
// initialize both to normal white color
#define FOREGROUND_WHITE (FOREGORUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN)
int g_console_out_color = FOREGROUND_WHITE;
int g_console_err_color = FOREGROUND_WHITE;
HANDLE g_console_out_handle = GetStdHandle(STD_OUTPUT_HANDLE);
HANDLE g_console_err_handle = GetStdHandle(STD_ERROR_HANDLE);
void SetConsoleOutColor(int color){
g_console_out_color = color;
}
void SetConsoleErrColor(int color){
g_console_err_color = color;
}
void PrintOut(const char* format, ...){
SetConsoleTextAttribute(g_console_out_handle, g_console_out_color);
va_list args;
va_start(args, str);
fprintf(stdout, format, args);
va_end(args);
// set color back to normal
SetConsoleTextAttribute(g_console_out_handle, FOREGROUND_WHITE);
}
void PrintErr(const char* format, ...){
SetConsoleTextAttribute(g_console_err_handle, g_console_err_color);
va_list args;
va_start(args, str);
fprintf(stderr, format, args);
va_end(args);
// set color back to normal
SetConsoleTextAttribute(g_console_err_handle, FOREGROUND_WHITE);
}
int main(void){
PrintOut("%s\n", "out");
PrintErr("%s\n", "err");
}
Upvotes: 5
Reputation: 2740
Try to set the color before each output. You can do that in a function to avoid code duplication.
Upvotes: 0