Перенаправление стандартного вывода - переключено с 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$ фактический файл, или функция рассматривает этот ввод как особый случай.

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