11

I know you should not mix printing with printf,cout and wprintf,wcout, but have a hard time finding a good answer why and if it is possible to get round it. The problem is I use a external library that prints with printf and my own uses wcout. If I do a simple example it works fine, but from my full application it simply does not print the printf statements. If this is really a limitation, then there would be many libraries out there which can not work together with wide printing applications. Any insight on this is more than welcome.

Update :

I boiled it down to :

#include <stdio.h>
#include <stdlib.h>
#include <iostream>

#include <readline/readline.h>
#include <readline/history.h>

int main()
{
    char *buf;

    std::wcout << std::endl; /* ADDING THIS LINE MAKES PRINTF VANISH!!! */

    rl_bind_key('\t',rl_abort);//disable auto-complete

    while((buf = readline("my-command : "))!=NULL)
    {
        if (strcmp(buf,"quit")==0)
            break;

        std::wcout<<buf<< std::endl;

        if (buf[0]!=0)
            add_history(buf);
    }

    free(buf);

    return 0;
}

So I guess it might be a flushing problem, but it still looks strange to me, I have to check up on it.

Update -> Work around :

First of all, the same problem arise with wprintf. But I found that adding :

std::ios::sync_with_stdio(false);

actually did the trick...(note false and not as I would expect true..), the only thing that bothers me, is that I don't understand why and how to figure it out :-(

Bo Jensen
  • 598
  • 5
  • 12
  • I boiled it down to the following : #include #include #include #include #include int main() { char *buf; std::wcout << std::endl; /* ADDING THIS LINE MAKES PRINTF VANISH!!! */ rl_bind_key('\t',rl_abort);//disable auto-complete while((buf = readline("my-command : "))!=NULL) { if (strcmp(buf,"quit")==0) break; std::wcout< – Bo Jensen Apr 25 '10 at 15:36
  • sorry my mistake obviously not to be used with code snippets. – Bo Jensen Apr 25 '10 at 15:37
  • 1
    Why answers are focusing on mixing `cout` and `printf`, while the question is about mixing `cout` and `wcout`... – kennytm Apr 25 '10 at 15:49
  • No its not, because inside the readline function, there are printf statements. – Bo Jensen Apr 25 '10 at 15:57
  • @Kenny: Because the title doesn't make that clear. I'll try to improve it. – Ben Voigt Apr 25 '10 at 16:08
  • I can confirm that (in my case) mixing _tprintf and wcout crashes the application (written with Visual Studio 2010). Reproducibly. – Helge Klein Jun 01 '12 at 21:34

5 Answers5

6

You should be able to mix them, but they typically use separate buffering mechanisms so they overlap each other:

printf("hello world");
cout << "this is a suprise";

can result in:

hellothis is a suprise world

You don't provide enough information to diagnose your problem with printf() in your application, but I suspect you have more than one c runtime (one in your code, one in the printf() code) and there is a conflict.

Lightness Races in Orbit
  • 369,052
  • 73
  • 620
  • 1,021
Chris Hafey
  • 601
  • 3
  • 5
  • What I do is using GNU readline library for commandline history. So my application is linked with this library. – Bo Jensen Apr 25 '10 at 14:19
  • 1
    I might add, that if we talk about mixing cout and wcout (and not printf and wcout), then it is my experience it is not just scrambled out thats a problem, the application can crash. Thanks for your answer. – Bo Jensen Apr 25 '10 at 14:26
  • @Bo Jensen: That's not wcout's fault. That's your fault. Either that or there's a bug in your C++ standard library implementation. – Billy ONeal Apr 25 '10 at 14:48
  • 2
    This should be very unlikely, though. By default, cout and C's output streams should be syncronized (http://www.cplusplus.com/reference/iostream/ios_base/sync_with_stdio/). Output that in a loop for some 100 times and see what it outputs. Then turn of syncronization and try again. – UncleBens Apr 25 '10 at 14:58
6

I think you're talking about std::ios_base::sync_with_stdio, but IIRC it is on by default.

Michael Krelin - hacker
  • 131,515
  • 23
  • 189
  • 171
2

The printf() and cout buffers are either synchronised by default, or are in fact the same buffer. If you are having problems with buffering, the obvious solution is to flush the buffer after each output:

fflush( stdout );
cout.flush();

this flushes the buffer(s) to the operating system, and once done there is no possibility of interleaving, or of output being lost.

1

Libraries should not use printf, cout, or any other I/O to standard handles. They should use a callback routine to delegate output to a method of the main program's choice.

An obvious exception is a library whose sole purpose is output, but then it's the main program's choice to use that. And this rule doesn't forbid I/O to file descriptors opened by the library.

Not only would that solve the issue raised here, but it also takes care of disconnected operation (linux program with no tty, eg run via nohup, or Win32 service).

Ben Voigt
  • 269,602
  • 39
  • 394
  • 697
0

buffering headaches. typically, you can, though, since they are synced. the people who tell you not to are probably people who remember the pain of using multiple io methods and want to save you from it. (just don't mix either with system calls. that would be painful.)

muhmuhten
  • 3,263
  • 1
  • 19
  • 26