Настройка цвета текста stdout/stderr в Windows

Я пытался с помощью system("color 24"); но это не изменило цвет в подсказке. Так что после еще прибегая к помощи я увидел SetConsoleTextAttribute и написал код ниже.

Это приводит как к stdout а также stderr оба окрашиваются в красный цвет вместо stdout быть зеленым и stderr быть красным

Как мне это решить? Моя подсказка также теперь красная, но меня это не волнует, так как я знаю, как это исправить.

Должно работать в Windows 7. На данный момент я собираю это из командной строки (используя VS 2010 cl) и запускаю его в обычном режиме. cmd незамедлительный

#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;
}

3 ответа

Решение

По данным MSDN GetStdHandle() документация, функция вернет дескрипторы в тот же активный экранный буфер консоли. Поэтому установка атрибутов с помощью этих дескрипторов всегда будет менять один и тот же буфер. Из-за этого вы должны указать цвет прямо перед устройством вывода:

/* ... */

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;

Дескриптор ошибки и нормального вывода на консоль совпадают. Или, скорее, они указывают на одно и то же окно консоли. Когда вы изменяете цвет консоли, он применяется ко всему тексту, написанному после этого, поэтому вам нужно будет изменить цвет непосредственно перед выводом. Если вы не хотите делать это для каждого выводимого текста, упакуйте вызовы в отдельную функцию:

#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");
}

Попробуйте установить цвет перед каждым выводом. Вы можете сделать это в функции, чтобы избежать дублирования кода.

Другие вопросы по тегам