0

I'm running some C++ code and have been noticing some weird behavior. For instance, my std::cout prints are only printing out a part of the string that I tell it to print.

Here is a small section of my code (this code gets called repeatedly):

std::ofstream file;
file.open("cout_img.txt", std::ofstream::out | std::ofstream::app);
std::streambuf* sbuf = std::cout.rdbuf();
std::cout.rdbuf(file.rdbuf());
std::cout << "Reached Display Function NOW";
std::string frame_file_name = std::string("demo") + std::to_string(saveImgNum) + std::string(".bmp");
std::cout << frame_file_name + '\n';

For instance, in this section I'm only printing out "splay Function NOW" each time instead of the full string "Reached Display Function NOW". I'm also not even printing out the frame_file_name variable.

Could this mean I'm experiencing a memory leak somewhere? If so, does the section of code I posted look suspicious at all? Is it because I have to deallocate variables such as the std::string variable?

What else can I look for? I'm using CPython API (Python embedded in C++) if that makes a difference.

Thanks so much!

cmed123
  • 675
  • 6
  • 18
  • The way to print a file is to use `cout << file.rdbuf()` rather than setting cout's buffer to file's buffer. Change that and see if you get what you expect. – Tanveer Badar Dec 17 '19 at 05:56
  • 1
    "Could this mean I'm experiencing a memory leak somewhere?" - unlikely. The symptoms of a memory leak is that the program memory use grows without obvious reason and eventually the program runs out of available memory. Not that it randomly behaves incorrectly. – Jesper Juhl Dec 17 '19 at 05:56
  • @TanveerBadar Thanks for your response! I want to be able to print directly into a file though. In this case, I want to print the string into the "cout_img.txt" file. – cmed123 Dec 17 '19 at 05:58
  • @JesperJuhl If I run the program long enough, I will run out of memory though. Is that what you mean? – cmed123 Dec 17 '19 at 05:59
  • 2
    Then why not use that ofstream itself? Like `file << "your content";`. I am still unable to understand why you are setting buffers. And you can probably control this on commandline directly by saying `&1>cout_txt` through redirection, rather than hard-coding it in your program. – Tanveer Badar Dec 17 '19 at 06:02
  • 2
    Two streams trying to share the same read buffer is a recipe for disaster. – David Schwartz Dec 17 '19 at 06:05
  • @DavidSchwartz Am I doing that now? Sorry not sure what you mean. – cmed123 Dec 17 '19 at 06:06
  • 1
    @cmed123 What do you think this does: `std::cout.rdbuf(file.rdbuf());`? – David Schwartz Dec 17 '19 at 06:07
  • @TanveerBadar I'm doing this via Visual Studio so I don't believe I can do redirection. This is a Windows program so I don't have an output console, so that's why I'm just displaying to files – cmed123 Dec 17 '19 at 06:07
  • This is an XY problem then. You need to open debug console/output console and verify all cout output goes to one of these tool windows. Don't change your program just because you cannot figure out how a particular IDE works. – Tanveer Badar Dec 17 '19 at 06:54
  • @TanveerBadar The Windows MFC framework doesn't have an output console though. Is there a way to open the console that I'm not aware of? – cmed123 Dec 17 '19 at 06:57
  • What exactly are you trying to do? Redirect all console output to a log file? – Everyone Dec 17 '19 at 07:37
  • @Everyone yup that's what I've been doing, but my core question is actually why only part of the print statement is being displayed. My guess was that it's a memory leak, but it doesn't seem that other people agree. – cmed123 Dec 17 '19 at 07:40

1 Answers1

0

If you just want to write to a file (as a console replacement / log), then there is no reason to redirect your output through std::cout.

I took your snippet and cut it down. This:

int main()
{
    std::ofstream file;
    file.open("cout_img.txt", std::ofstream::out | std::ofstream::app);

    file << "Reached Display Function NOW\n";
    std::string frame_file_name = std::string("demo") + std::to_string(17 /*saveImgNum*/) + std::string(".bmp");
    file << frame_file_name + '\n';

    return 0;
}

Produces a file cout_img.txt containing:

Reached Display Function NOW
demo17.bmp

EDIT: Additionally, you can also enable the console in your windows app. A quick search lead to this answer. Add the following code to your WinMain, and the console will work:

    AllocConsole();
    #pragma warning( disable : 4996 )
    freopen("conin$", "r", stdin);
    freopen("conout$", "w", stdout);
    freopen("conout$", "w", stderr);
    printf("Debugging Window:\n");
    std::cout << "Testing the console 1 2 3" << std::endl;

If you do a more thorough search, you can probably even find a method that doesn't use a deprecated method (freopen). But as shown there it did add a functioning console to the windows app that I just created to test with.

Frodyne
  • 3,547
  • 6
  • 16
  • Thank you very much! For your second solution regarding the AllocConsole(), it seems that the cout to that only works if it's in scope, right? If I do cout in a different function, it won't print to that console – cmed123 Dec 17 '19 at 07:38
  • @cmed123 that is incorrect. AllocConsol will work the same for any `std::cout` unless you modify `std::cout` to behave differently. If you wish to have your console automatically show up, you could just change the project properties in VS to be a `Console Application` – Everyone Dec 17 '19 at 07:40
  • @Everyone Thank you for clarifying. You're right, I just tested that as well. It turns out, though, that the console cannot display Python output if I'm using the CPython API. Is it because Python goes through a different output location? Unless I'm mistaken again – cmed123 Dec 17 '19 at 07:51
  • @cmed123 if you're running child process, it got ow output stream. All you can do is connect it, similar to what Visual Studio does for compile tools. Ther was answer to that problem on SO somewhere, apparently you were solving XY problem. – Swift - Friday Pie Dec 17 '19 at 10:21