stdout 输出不会显示在基于 Windows MFC 对话框的应用程序的控制台上

vac*_*ead 3 c++ windows mfc visual-studio

我正在尝试做什么

我正在使用 Visual Studio 编写一个简单的基于对话框的程序。它按其应有的方式履行其主要职能。然后我添加了对从命令提示符运行应用程序的支持。当我从命令行提示符调用该程序时,它仍然运行良好,但写入stdout或的任何消息stderr都不会显示。

我尝试过的

我尝试过多种变体_tprintf()_ftprintf(stdout, etc)等等。不管怎样,我在控制台上没有得到任何输出。

它如何决定是否显示对话框

当命令行包含至少两个参数时,程序会绕过对话框,直接执行程序的主要逻辑,该逻辑体现在函数中Go(arg1, arg2)。当命令行没有足够的参数时,将使用对话框。

我的代码

这是一个非常精简的例子。剩下的大部分内容是由 Visual Studio 生成的,我刚刚添加了几行我自己的代码。该示例实际上不会编译,因为存在未解析的外部引用。

BOOL CCNCSplineApp::InitInstance()
{
    // InitCommonControlsEx() is required on Windows XP if an application
    // manifest specifies use of ComCtl32.dll version 6 or later to enable
    // visual styles.  Otherwise, any window creation will fail.
    INITCOMMONCONTROLSEX InitCtrls;
    InitCtrls.dwSize = sizeof(InitCtrls);
    // Set this to include all the common control classes you want to use
    // in your application.
    InitCtrls.dwICC = ICC_WIN95_CLASSES;
    InitCommonControlsEx(&InitCtrls);
    std::time_t* p_clock = &time_now;

    CWinApp::InitInstance();
    AfxEnableControlContainer();

    // Create the shell manager, in case the dialog contains
    // any shell tree view or shell list view controls.
    CShellManager *pShellManager = new CShellManager;

    // Standard initialization
    SetRegistryKey(_T("MyCompany"));

    LPCTSTR cmdline = ::GetCommandLineW();
    int argc;
    LPWSTR* argv = ::CommandLineToArgvW(cmdline, &argc);
    if (2 < argc)
    {
        FILE*tgt = _tfopen(argv[2], _T("w"));
        if (0 == tgt)
        {
            _tprintf(L"Unable to open output file \"%s\"\n", argv[2]);
            exit(-1);
        }
        CString inputFileName = argv[1];
        Go(inputFileName, tgt);
        CString status = StatusText();
        if (status.GetLength() > 0)
        {
            _tprintf(_T("%s\n"), (LPCTSTR)status);
        }
        return FALSE;
    }

    MyDialog dlg;
    m_pMainWnd = &dlg;
    dlg.DoModal();

    // Delete the shell manager created above.
    if (pShellManager != NULL)
    {
        delete pShellManager;
    }

    // Since the dialog has been closed, return FALSE so that we exit the
    //  application, rather than start the application'time_doa message pump.
    return FALSE;
}
Run Code Online (Sandbox Code Playgroud)

问题

我需要对此代码进行哪些更改才能获得各种_tprintf()调用以在控制台上显示文本?

zet*_*t42 5

将此代码插入到InitInstance()、 之后printf()std::cout位置应该可以工作:

if( AttachConsole( ATTACH_PARENT_PROCESS ) )
{
    freopen( "CONIN$",  "rb", stdin );   // reopen stdin handle as console window input
    freopen( "CONOUT$", "wb", stdout );  // reopen stdout handle as console window output
    freopen( "CONOUT$", "wb", stderr );  // reopen stderr handle as console window output
}
Run Code Online (Sandbox Code Playgroud)

您可能还需要调用_setmode(_fileno(stdout), _O_U16TEXT)(same for stderr) 来启用到控制台的 Unicode 输出