【问题标题】:VS2017 MFC could not output message to consoleVS2017 MFC 无法向控制台输出消息
【发布时间】:2018-04-16 07:23:10
【问题描述】:

我创建了一个基于 MFC 对话框的应用程序。在 VS2013 中,我可以创建一个控制台窗口并输出消息。当我升级到 VS2017 时,执行相同的代码,创建控制台窗口但没有消息输出。以下是我的代码:

bool Initialize(void)
{
    HWND hWnd = GetConsoleWindow();
    if (NULL != hWnd)
    {
        return true;
    }

    if (!AllocConsole())
    {
        return false;
    }

    HANDLE m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if (INVALID_HANDLE_VALUE == m_hStdOut)
    {
        return false;
    }

    int m_hCrt = _open_osfhandle((intptr_t)m_hStdOut, _O_TEXT);
    if (-1 == m_hCrt)
    {
        return false;
    }

    FILE* m_pCrtFile = _fdopen(m_hCrt, "w");
    *stdout = *m_pCrtFile;
    int ret = setvbuf(stdout, NULL, _IONBF, 0);
    if (-1 == ret)
    {
        return false;
    }
    return true;
}

void WriteLine(LPCTSTR lpszText)
{
    Initialize();
    std::wcout << lpszText;
    std::wcout << std::endl;
    std::wcout.flush();
    system("pause");
}

BOOL CMFCApplication1App::InitInstance()
{
    WriteLine(_T("test"));
    ...
}

问题: 我应该如何修改我的代码以在 VS2017 中将消息输出到控制台?

【问题讨论】:

  • 来自stdin, stdout, stderr: "这些指针是常量,不能被赋予新的值。freopen 函数可用于将流重定向到磁盘文件或其他设备。" 代码行*stdout = *m_pCrtFile; 无效。如果它看起来有效,那只是巧合。

标签: c++ mfc console visual-studio-2017


【解决方案1】:

添加对freopen(或freopen_s 以避免安全警告)的调用以重新打开stdout。还要添加_dup2 以将stdout 与控制台的文件描述符相关联。

需要_setmode(_fileno(stdout), _O_U16TEXT) 打印Unicode(除非您将模式设置回_O_TEXT,否则std::cout 将不可用)。

另见Redirecting cout

bool Initialize()
{
    if(GetConsoleWindow())
        return true;

    if(!AllocConsole())
        return false;

    HANDLE m_hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    if(m_hStdOut == INVALID_HANDLE_VALUE)
        return false;

    //get file descriptor from handle
    int m_hCrt = _open_osfhandle((intptr_t)m_hStdOut, _O_TEXT);
    if(m_hCrt == -1)
        return false;

    FILE* m_pCrtFile = _fdopen(m_hCrt, "w");
    if(!m_pCrtFile)
        return false;

    FILE* notused;
    freopen_s(&notused, "CONOUT$", "w", stdout);

    //associate m_pCrtFile with `stdout`
    if(_dup2(_fileno(m_pCrtFile), _fileno(stdout)) != 0)
        return false;

    setvbuf(stdout, NULL, _IONBF, 0);

    _setmode(_fileno(stdout), _O_U16TEXT);
    std::wcout << L"123 ελληνικά Иванчо English\n";
    return true;
}

【讨论】:

    猜你喜欢
    • 2015-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多