Does setbuf() affect cout? - c++

Yet again, my teacher was unable to answer my question. I knew who may be able to...
So, I've never really learned C. In C++, I would, obviously, use a cout statement all of the time. In a recent assignment, my teacher told us to make sure to put
setbuf( stdout , NULL );
at the top of main() in order to get an unbuffered output, thus allowing us to see the output properly.
My question is this: will this statement affect a cout statement, or simply a printf() statement that I call?
Thanks in advance!

By default, iostreams and stdio are synchronised. Reference.
This doesn't mean that manually adjusting the stdio buffering is a good idea, though! You may wish to utilise std::endl or std::flush (from <ostream>), which may help you. e.g.,
std::cout << "Hello, world!" << std::endl;
or
std::cout << "Hello, world!\n" << std::flush;
Both of these do the same thing. (std::endl = print endline, then flush.)

By default, if stdout or cout is printing to a console, the output is line buffered. This means that every newline that is printed will flush the output. You can explicitly call flush() whenever you want to override the behavior just in case say, the output is going to be redirected to a file and you want to use tail -f and need certain outputs in realtime.
As Chris said, sync_with_stdio should tie the unbuffered stdout with an unbuffered cout (by default), but if all you are doing is using cout, instead of using setbuf on stdout, a better option is to use pubsetbuf on the pointer returned by rdbuf. ie:
// make cout unbuffered
std::cout.rdbuf()->pubsetbuf(0, 0);
Another function that may be interesting to look at is tie.

Usually, when it's important to see the output immediately, we're talking about complex highly-reliable financial routine that must log a transaction all the way to hard drive before actually sending it to counterparty. Or, (much more common case) we want to see debug messages even when the program is crashing.
Since you're studying, I'll assume you're dealing with the second case. In that case, my advice would be to use stderr rather than stdout. It is unbuffered by default, and you can redirect it separately from stdout, putting your output in one place and your logging in another.

Related

Question std::cout in C++ how exactly does the stream work?

Say we have:
std::cout << "Something";
How exactly is this working? I just want to make sure I understand this well and, from what I've been reading, is it okay to say that basically the insertion operator inserts the string literal "Something" into the standard output stream?
But what happens after that? Where does the standard output stream lead? Can anyone explain this?
That's basically the only part I don't get: I have the string literal "Something" in the standard output stream, but where does the stream lead?
The technical details vary between the different Operating Systems, but the basics are the same:
Every program has usually 3 standard streams: out (cout), in (cin), and err (cerr) (same as out, but used for errors). Those streams are nothing on their own; they exist to be used by a third party. That third party may be, for example, the terminal. When you execute a program form the terminal, it attaches to the program streams and show their output/request their input in the terminal.
If you wanted to do the same, you could execute a command yourself from your program, and take the out/in/err streams to read or write from/to them.
You have an example of that here: How do I execute a command and get the output of the command within C++ using POSIX?
Edit: When talking about C++, remember that cout << "anything" is just syntactic sugar for the function cout.operator<<("anything"). And that function "simply" writes to the stream
so,'std' is the namespace in which is stored everything found in the standard library , so basically you are saying "hey C++, go to 'std' storage and find cout command and run it" at least I know 'std' is this. and when you are saying using namespace std; you tell the compiler "take everything that's in the std namespace and dump it in the global namespace".
I hope it helped you to understand.

Is there a way to determine in C++ whether Mac stdout is pointing to the console? [duplicate]

Well, the subject says it all, basically.
I have a command-line utility that may be used interactively or in scripts, using pipes or i/o redirection. I am using cin and cout for i/o, and I want to write an extra EOL at the end if the output is console, so that user prompt will start from the next line. Within scripts this would be harmful.
Can I assume cin == 0, cout == 1? I understand that there is no clean way to get the file descriptor of a stream. Or is it?
If using Linux (and probably other unixes, but definitely not Windows) you could try isatty.
There's no direct way of extracting the file descriptor from the C++ stream. However, since in a C++ program both cout as well as stdout exist and work at the same time (C++ by default provides synchronisation between stdio and iostream methods), your best bet in my opinion is to do a isatty(fileno(stdout)).
Make sure you #include <unistd.h>.
It is possible to use rdbuf() to change the destination of std::cin and std::cout inside your program. If you don't do that, it is probably quite safe to assume that cin = 0, cout=1 and clog and cerr both = 2 as the C++ standard states that they are synchronized with C stdin, stdout and stderr and those have per POSIX those file descriptors at startup.

C++ reset locale to "C" globally?

In a project I am currently working on I link to a proprietary dynamic library. As soon as I run the library's initialize function, the behavior of logging and printing of numbers changes.
Commas have been inserted at every third decimal. i.e.
cout << 123456789 << endl
used to print out 123456789 and now it prints 123,456,789. This is horribly annoying, because this behavior is not what I want.
This issue is not only apparent in the binary I am compiling, but also shows up in all the couts and stringstreams in the libraries that I link to it.
I have tried using this line of code after calling the initialize function:
setlocale(LC_ALL,"C");
thinking it might reset my locale to the default but to no avail. The commas persist!
This snippet of code:
std::cout.imbue(std::locale("C"));
works to reset the locale of couts and every stringstream I apply it too. However, do I really need to call imbue on EVERY stringstream declared in EVERY library I link to? There are some libraries that are proprietary and I cannot actually change their source code.
There must be a way to reset the locale back to "C" globally?
I believe std::locale::global(std::locale("C")); should do the trick. See http://en.cppreference.com/w/cpp/locale/locale/global
Note that this only affects streams created after this call.
Any streams such as cout that the other library already imbued would have to be re-imbued back to the desired default locale.
And finally I would strongly suggest filing a defect report against the library you're using because it's pretty unjustifiable to to unilaterally make such striking global changes within your initialization function.

how to use isatty() on cout, or can I assume that cout == file descriptor 1?

Well, the subject says it all, basically.
I have a command-line utility that may be used interactively or in scripts, using pipes or i/o redirection. I am using cin and cout for i/o, and I want to write an extra EOL at the end if the output is console, so that user prompt will start from the next line. Within scripts this would be harmful.
Can I assume cin == 0, cout == 1? I understand that there is no clean way to get the file descriptor of a stream. Or is it?
If using Linux (and probably other unixes, but definitely not Windows) you could try isatty.
There's no direct way of extracting the file descriptor from the C++ stream. However, since in a C++ program both cout as well as stdout exist and work at the same time (C++ by default provides synchronisation between stdio and iostream methods), your best bet in my opinion is to do a isatty(fileno(stdout)).
Make sure you #include <unistd.h>.
It is possible to use rdbuf() to change the destination of std::cin and std::cout inside your program. If you don't do that, it is probably quite safe to assume that cin = 0, cout=1 and clog and cerr both = 2 as the C++ standard states that they are synchronized with C stdin, stdout and stderr and those have per POSIX those file descriptors at startup.

Internal "Tee" setup

I have inherited some really old VC6.0 code that I am upgrading to VS2008 for building a 64-bit app. One required feature that was implemented long, long ago is overriding std::cout so its output goes simultaneously to a console window and to a file. The implementation depended on the then-current VC98 library implementation of ostream and, of course, is now irretrievably broken with VS2008. It would be reasonable to accumulate all the output until program termination time and then dump it to a file. I got part of the way home by using freopen(), setvbuf(), and ios::sync_with_stdio(), but to my dismay, the internal library does not treat its buffer as a ring buffer; instead when it flushes to the output device it restarts at the beginning, so every flush wipes out all my accumulated output. Converting to a more standard logging function is not desirable, as there are over 1600 usages of "std::cout << " scattered throughout almost 60 files. I have considered overriding ostream's operator<< function, but I'm not sure if that will cover me, since there are global operator<< functions that can't be overridden. (Or can they?)
Any ideas on how to accomplish this?
You could write a custom stream buffer and attach it to cout with cout.rdbuf(). Your custom stream buffer would then tee the data to cout's original stream buffer and to a stream buffer stolen from an appropriate ofstream.
ofstream flog("log.txt");
teebuf tb(flog.rdbuf(), cout.rdbuf());
cout.rdbuf(&tb);
For your teeing stream buffer you can get an inspiration from this page.
You could use the pre-processor:
#define cout MyLogger
to inject new code.