У меня есть приложение, которое является относительно старым. С некоторыми незначительными изменениями он почти отлично сочетается с Visual С++ 2008. Одна вещь, которую я заметил, это то, что моя "консоль отладки" работает не совсем правильно. В основном в прошлом я использовал AllocConsole()
для создания консоли для вывода моего отладки. Затем я использовал бы freopen
для перенаправления stdout
на него. Это отлично работало с IO типа C и С++.
Теперь кажется, что он будет работать только с C style IO. Каким образом можно перенаправить такие вещи, как cout
на консоль, выделенную с помощью AllocConsole()
?
Вот код, который использовался для работы:
if(AllocConsole()) {
freopen("CONOUT$", "wt", stdout);
SetConsoleTitle("Debug Console");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
}
EDIT: одна вещь, которая пришла мне в голову, - это то, что я могу создать пользовательский streambuf, метод переполнения которого записывается с использованием стиля C style IO и заменяет его буфером по умолчанию std::cout
. Но это похоже на отказ. Есть ли правильный способ сделать это в 2008 году? Или это, возможно, то, что MS игнорирует?
EDIT2: Хорошо, поэтому я сделал реализацию идеи, изложенной выше. В основном это выглядит так:
class outbuf : public std::streambuf {
public:
outbuf() {
setp(0, 0);
}
virtual int_type overflow(int_type c = traits_type::eof()) {
return fputc(c, stdout) == EOF ? traits_type::eof() : c;
}
};
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) {
// create the console
if(AllocConsole()) {
freopen("CONOUT$", "w", stdout);
SetConsoleTitle("Debug Console");
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED);
}
// set std::cout to use my custom streambuf
outbuf ob;
std::streambuf *sb = std::cout.rdbuf(&ob);
// do some work here
// make sure to restore the original so we don't get a crash on close!
std::cout.rdbuf(sb);
return 0;
}
У любого есть лучшее/более чистое решение, чем просто заставить std::cout
быть прославленным fputc
?