2
votes

I have something weird happening where printf commands (inside a class constructor) are not being output to the console window.

Do you know why this would happen?

Some relevant information:

  • My project is a Native Win32 Windowed Application(not a Win32 Console Project)
  • I open the console window using AllocConsole() & _open_osfhandle().
  • The constructor that I call the printf commands from is part of a Singleton class and inside the private constructor I call a static function isTVManagerTaskScheduled().
  • If I use printf outside of the constructor then it works correctly, ie, data is printed to the console window.
  • The console window is used just for debugging my Win32 Application.
  • I am using C++ Visual Studio 2010 Express
  • If I dont call the static function isTVManagerTaskScheduled() from within the constructor then the printf's work correctly.

Do you know why this would happen?

My code:

// Public Static Class Variables //
const tstring TVManager::TASK_NAME          = _T("TV Manager");
const tstring TVManager::TASK_TIME_STAMP    = _T("2012-03-22T13:46:00");

// Private constructor
TVManager::TVManager(HWND hwnd)
{
    mainHwnd = hwnd;

    bool res = isTVManagerTaskScheduled();
    std::cout << "Res: " << res << endl; // does not print to console
    _tprintf(_T("RES: %d\n"), res);      // does not print to console

    if (!res) {
        _tprintf(_T("hit\n"));
        EasyTaskScheduler::ScheduleTaskAtLogon(TASK_NAME, CPP_Utilities::getProcessPath(), TASK_TIME_STAMP);
    }
}

// Public Static function //
bool TVManager::isTVManagerTaskScheduled()
{
    std::vector <tstring> curTasks = EasyTaskScheduler::RetrieveScheduledTasks();
    tstring defTaskName            = CPP_Utilities::toLower( TASK_NAME );

    for (int i=0; i<=curTasks.size(); i++) {
        tstring task = CPP_Utilities::toLower(curTasks.at(i));
        // The following printf doesn't get printed to console
        _tprintf(_T("size %d, Task %d: %s\n"), curTasks.size(), i, task.c_str());
        if (task.find( defTaskName ) != npos) {
            _tprintf(_T("returning true\n"));
            return true;
        }
    }

    _tprintf(_T("returning false\n"));
    return false;
}

// Public static function
TVManager* TVManager::getInstance(HWND hwnd)
{
    static TVManager instance(hwnd);
    return &instance;
}

// Usage: Inside main window proceedure
case WM_CREATE:
{
    CPP_Utilities::openConsoleWindow();
    tvManager = TVManager::getInstance(hwnd);
}
break;
2
maybe your object is constructed before the console is there? It's hard to say since you didn't really give us a working example. - Guy Sirton
curTasks.size() is unsigned, so not %d. - chris
@GuySirton Please see edits for how the class is used. But I am sure that the console exists prior to calling the constructor because other things are written to the console by that point. - sazr
@ChrisDesjardins do you mean just manually write lines to a text file or use a Visual Studio logfile(if they exist?) - sazr
Can you pare down the example code to a self-contained repro example? - Michael Burr

2 Answers

1
votes

The problem was I was accessing an invalid vector element here:

for (int i=0; i<=curTasks.size(); i++) {
   tstring task = CPP_Utilities::toLower(curTasks.at(i));

It should be:

for (int i=0; i<curTasks.size(); i++) {

The weird thing is that it never threw a runtime error or crashed. It just continue working except it didn't output anything to the console.

0
votes

The absolute easiest, and most portable solution is to just open an output file with fopen or ofstream, and write to it, you can also output to the MSVC output console:

How do I print to the debug output window in a Win32 app?

but obviously that limits you to debugging with MSVC.