重定向标准输出 - 从VS2013切换到VS2017,写入异常

时间:2017-07-29 14:24:58

标签: c++ visual-studio visual-studio-2017 redirectstandardoutput

我最近将项目从使用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时,会抛出以下异常(否则它不会写入输出并从此静默失败):

Debug Assertion失败!

程序:w:\ build \ MyApp.exe 文件:minkernel \ crts \ ucrt \ src \ appcrt \ stdio_flsbuf.cpp 行:26

表达式:(&#34;不一致的IOB字段&#34;,stream-&gt; _ptr-stream-&gt; _base&gt; = 0)

有关程序如何导致断言的信息 失败,请参阅关于断言的Visual C ++文档。

(按“重试”调试应用程序)

我可以看到stdout来自corecrt_wstdio.h,但是当我插入断点并添加一个监视时,它表示stdout未定义,所以我无法检查该值。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

所以我搜索了一下,发现this post on SO.

基本上,我发布的所有代码都可以替换为以下内容:

freopen(&#34; CONOUT $&#34;,&#34; w&#34;,stdout);

freopen的第一个参数是文件名,所以我想知道CONOUT $ / CONIN $是否代表一个实际文件,或者该函数是否将该输入视为特殊情况。