1

I create a MFC dialog based application. In VS2013, I could create a console window and output message. When I upgraded to VS2017, execute same code, the console window is created but no message output. Below is my code:

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"));
    ...
}

Question: How should I modify my code to output message to console in VS2017?

Kerwen
  • 516
  • 5
  • 22
  • From [stdin, stdout, stderr](https://learn.microsoft.com/en-us/cpp/c-runtime-library/stdin-stdout-stderr): *"These pointers are constants, and cannot be assigned new values. The `freopen` function can be used to redirect the streams to disk files or to other devices."* The line of code `*stdout = *m_pCrtFile;` is invalid. If it appears to work, it does so by coincidence only. – IInspectable Apr 16 '18 at 07:33

1 Answers1

3

Add a call to freopen (or freopen_s to avoid security warnings) to reopen stdout. Also add _dup2 to associate stdout with console's file descriptor.

_setmode(_fileno(stdout), _O_U16TEXT) is needed print Unicode (std::cout will not be available unless you set the mode back to _O_TEXT).

See also 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;
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77