Я недавно переключил проект с использования компилятора VS2013 на VS2017, и теперь следующий код, похоже, не работает:
#include <windows.h>
#include <Fcntl.h>
#include <io.h>
#include <iostream>
#include <exception>
if( RedirectOutput )
{
//Setup stdout
HANDLE handle_stdout = GetStdHandle( STD_OUTPUT_HANDLE );
int fileDesc_stdout = _open_osfhandle( (long)handle_stdout, _O_TEXT );
if( fileDesc_stdout == -1 )
{
throw std::exception( "fileDesc_stdout is not valid" );
}
FILE* new_stdout = _fdopen( fileDesc_stdout, "w" );
if( !new_stdout )
{
throw std::exception( "new_stdout is not valid" );
}
FILE old_stdout = *stdout;
*stdout = *new_stdout;
std::cout.clear();
std::cout << "Output Redirected!\n";
}
Этот код предназначен для перенаправления стандартного вывода в окно консоли, либо того, которое запускает текущий процесс, либо консоли, созданной через AllocConsole. (Я добавил последнюю строку для целей тестирования.)
В первый раз, когда происходит запись в cout, выдается следующее исключение (в противном случае он не записывает выходные данные и с тех пор завершается с ошибкой):
Ошибка отладки!
Программа: w: \ build \ MyApp.exe
Файл: minkernel \ crts \ ucrt \ src \ appcrt \ stdio_flsbuf.cpp
Линия: 26
Выражение: («несогласованные поля IOB», stream -> _ ptr — stream -> _ base> = 0)
Для получения информации о том, как ваша программа может вызвать утверждение
ошибка, см. документацию по Visual C ++ для подтверждений.
(Нажмите «Повторить» для отладки приложения)
Я вижу, что стандартный вывод исходит из corecrt_wstdio.h, но когда я вставляю точку останова и добавляю часы, он говорит, что стандартный вывод не определен, поэтому я не могу проверить значение.
Есть идеи?
Поэтому я немного обыскал и нашел этот пост на ТАК.
По сути, весь код, который я разместил, можно заменить следующим:
freopen («CONOUT $», «w», stdout);
Первым параметром freopen является имя файла, поэтому мне интересно, представляет ли CONOUT $ / CONIN $ фактический файл, или функция рассматривает этот ввод как особый случай.
Других решений пока нет …