When developing code, I have many console logging (std::clog) and some console output (std::cout). But now, I wanted to do online submission of my source code and I want to disable all the console logging (clog) but keep the console output (cout)
I can surely comment all of my //std::clog, but is there a better way to disable all logging inside my source file,?
You can redirect clog, create your own ofstream and use rdbuf function.
std::ofstream nullstream;
std::clog.rdbuf(nullstream.rdbuf());
Copied from Andreas Papadopoulos' answer to a slightly different question -- be sure to upvote him there!
Sure, you can (example here):
int main() {
std::clog << "First message" << std::endl;
std::clog.setstate(std::ios_base::failbit);
std::clog << "Second message" << std::endl;
std::clog.clear();
std::clog << "Last message" << std::endl;
return 0;
}
Outputs:
First message
Last message
This is because putting the stream in fail state will make it silently discard any output, until the failbit is cleared.
Related
Is there any circumstance when std::cout << "hello" doesn't work? I have a c/c++ code, however the std::cout doesn't print anything, not even constant strings (such as "hello").
Is there any way to check if cout is able/unable to open the stream? There are some member functions like good(), bad(), ... but I don't know which one is suitable for me.
Make sure you flush the stream. This is required because the output streams are buffered and you have no guarantee over when the buffer will be flushed unless you manually flush it yourself.
std::cout << "Hello" << std::endl;
std::endl will output a newline and flush the stream. Alternatively, std::flush will just do the flush. Flushing can also be done using the stream's member function:
std::cout.flush();
std::cout won't work on GUI apps!
Specific to MS Visual Studio:
When you want a console application and use MS Visual Studio, set project property "Linker -> System -> SubSystem" to Console. After creating a new Win32 project (for a native C++ app) in Visual Studio, this setting defaults to "Windows" which prevents std::cout from putting any output to the console.
To effectively disable buffering you can call this:
std::setvbuf(stdout, NULL, _IONBF, 0);
Alternatively, you can call your program and disable output buffering in the command line:
stdbuf -o 0 ./yourprogram --yourargs
Keep in mind this is not usually done for performance reasons.
It is probable that std::cout doesn't work due to buffering (what you're writing ends up in the buffer of std::cout instead of in the output).
You can do one of these things:
flush std::cout explicitly:
std::cout << "test" << std::flush; // std::flush is in <iostream>
std::cout << "test";
std::cout.flush(); // explicitly flush here
std::cout << "test" << std::endl; // endl sends newline char(s) and then flushes
use std::cerr instead. std::cerr is not buffered, but it uses a different stream (i.e. the second solution may not work for you if you're interested in more than "see message on console").
I don't get why "cout" outputs after the file is written, it makes no sense to me... How would I do it correctly? I tried with sleep between the two, but it's still not reversing the order like I want to.
cout << "Writing to file";
fp = fopen("plume_visualisation.txt","w");
for(int i=0;i<grid;i++)
for(int j=0;j<grid;j++)
for(int k=0;k<grid;k++)
fprintf(fp,"%f\t%f\t%f\t%f\n",x[i],y[j],z[k],suv[i][j][k]);
fclose(fp);
C++ writes to the output stream, stored in a buffer. You need to flush the buffer to write it to the console. Remember how you probably learned to write a line to the console?
std::cout << "This is a message" << std::endl;
What std::endl does is place a newline character at the end of the message, and flush the buffer. Based on your code, I'm guessing you thought "Hey, I can just leave off endl and it won't write a new line." This is a good way to think...but you probably didn't realize that endl also flushes the buffer. This is what you want:
std::cout << "Writing to file" << std::flush;
Also notice how I prefixed cout and flush with "std." Using "using namespace standard" is bad practice that you should avoid.
On a related note, you're already using C++. Instead of doing file IO the old C way of fprintf, instead set up a file stream. It works pretty much the same way that console IO does. Here's a great guide on how to do what you're doing in a more idiomatic fashion: http://www.cplusplus.com/doc/tutorial/files/
I often use cout for debugging purpose in many different places in my code, and then I get frustrated and comment all of them manually.
Is there a way to suppress cout output in the runtime?
And more importantly, let's say I want to suppress all cout outputs, but I still want to see 1 specific output (let's say the final output of the program) in the terminal.
Is it possible to use an ""other way"" of printing to the terminal for showing the program output, and then when suppressing cout still see things that are printed using this ""other way""?
Sure, you can (example here):
int main() {
std::cout << "First message" << std::endl;
std::cout.setstate(std::ios_base::failbit);
std::cout << "Second message" << std::endl;
std::cout.clear();
std::cout << "Last message" << std::endl;
return 0;
}
Outputs:
First message
Last message
This is because putting the stream in fail state will make it silently discard any output, until the failbit is cleared.
To supress output, you can disconnect the underlying buffer from cout.
#include <iostream>
using namespace std;
int main(){
// get underlying buffer
streambuf* orig_buf = cout.rdbuf();
// set null
cout.rdbuf(NULL);
cout << "this will not be displayed." << endl;
// restore buffer
cout.rdbuf(orig_buf);
cout << "this will be dispalyed." << endl;
return 0;
}
Don't use cout for debugging purposes, but define a different object (or function, or macro) that calls through to it, then you can disable that function or macro in one single place.
You can user cerr - standard output stream for errors for your debug purposes.
Also, there is clog - standard output stream for logging.
Typically, they both behave like a cout.
Example:
cerr << 74 << endl;
Details: http://www.cplusplus.com/reference/iostream/cerr/
http://www.cplusplus.com/reference/iostream/clog/
If you include files which involve cout you may want to write the code at the start (outside of main), which can be done like this:
struct Clearer {
Clearer() { std::cout.setstate(std::ios::failbit); }
} output_clearer;
It seems you print debug messages. You could use TRACE within Visual C++/MFC or you just might want to create a Debug() function which takes care of it. You can implement it to turn on only if a distinct flag is set. A lot of programs use a command line parameter called verbose or -v for instance, to control the behavior of their log and debug messages.
Is there any circumstance when std::cout << "hello" doesn't work? I have a c/c++ code, however the std::cout doesn't print anything, not even constant strings (such as "hello").
Is there any way to check if cout is able/unable to open the stream? There are some member functions like good(), bad(), ... but I don't know which one is suitable for me.
Make sure you flush the stream. This is required because the output streams are buffered and you have no guarantee over when the buffer will be flushed unless you manually flush it yourself.
std::cout << "Hello" << std::endl;
std::endl will output a newline and flush the stream. Alternatively, std::flush will just do the flush. Flushing can also be done using the stream's member function:
std::cout.flush();
std::cout won't work on GUI apps!
Specific to MS Visual Studio:
When you want a console application and use MS Visual Studio, set project property "Linker -> System -> SubSystem" to Console. After creating a new Win32 project (for a native C++ app) in Visual Studio, this setting defaults to "Windows" which prevents std::cout from putting any output to the console.
To effectively disable buffering you can call this:
std::setvbuf(stdout, NULL, _IONBF, 0);
Alternatively, you can call your program and disable output buffering in the command line:
stdbuf -o 0 ./yourprogram --yourargs
Keep in mind this is not usually done for performance reasons.
It is probable that std::cout doesn't work due to buffering (what you're writing ends up in the buffer of std::cout instead of in the output).
You can do one of these things:
flush std::cout explicitly:
std::cout << "test" << std::flush; // std::flush is in <iostream>
std::cout << "test";
std::cout.flush(); // explicitly flush here
std::cout << "test" << std::endl; // endl sends newline char(s) and then flushes
use std::cerr instead. std::cerr is not buffered, but it uses a different stream (i.e. the second solution may not work for you if you're interested in more than "see message on console").
Is it in good style do use cerr in situation described below?
try
{
cout << a + b;
}
catch(const IntException& e)
{
cerr << "Exception caught: " << typeid(e).name(); //using cerr not cout
}
catch(...)
{
cerr << "Unknown exception.";//using cerr not cout
}
or cout should be used? See comments in code.
stderr is the traditional stream to send error messages (so that the OS/shell/whatever can capture error messages separately from "normal" output), so yes, use std::cerr!
I make no comment as to whether catching an exception simply to print it out is any better than simply letting the exception propagating out of your application...
Yes, because while by default they both go to the terminal, you could change where their output is directed, and you may wish cerr to go to a log file while cout continues to just go to stdout.
Essentially it gives you more control over where different output goes if you want it now or in the future.
Sure, it's good to use cerr there. You can redirect cerr differently from cout, sometimes that helps you to highlight problems that could go buried in a huge cout log file.
One detail to keep in mind is that sending output directly to the terminal (with either cout or cerr), you do limit your ability to test for your error messages. It's always worth posing the question "How do I unit test this?".