Перенаправление стандартного вывода - переключено с VS2013 на VS2017, исключение при записи
Я недавно переключил проект с использования компилятора 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, но когда я вставляю точку останова и добавляю часы, он говорит, что стандартный вывод не определен, поэтому я не могу проверить значение.
Есть идеи?
1 ответ
Поэтому я немного искал и нашел этот пост на SO.
По сути, весь код, который я разместил, можно заменить следующим:
freopen ("CONOUT $", "w", stdout);
Первым параметром freopen является имя файла, поэтому мне интересно, представляет ли CONOUT$/CONIN$ фактический файл, или функция рассматривает этот ввод как особый случай.