I have a requirement, I need to use printf and cout to display the data into console and file as well.
For printf I have done it but for cout I am struggling, how to do it?
#ifdef _MSC_VER
#define GWEN_FNULL "NUL"
#define va_copy(d,s) ((d) = (s))
#else
#define GWEN_FNULL "/dev/null"
#endif
#include <iostream>
#include <fstream>
using namespace std;
void printf (FILE * outfile, const char * format, ...)
{
va_list ap1, ap2;
int i = 5;
va_start(ap1, format);
va_copy(ap2, ap1);
vprintf(format, ap1);
vfprintf(outfile, format, ap2);
va_end(ap2);
va_end(ap1);
}
/* void COUT(const char* fmt, ...)
{
ofstream out("output-file.txt");
std::cout << "Cout to file";
out << "Cout to file";
}*/
int main (int argc, char *argv[]) {
FILE *outfile;
char *mode = "a+";
char outputFilename[] = "PRINT.log";
outfile = fopen(outputFilename, mode);
char bigfoot[] = "Hello
World!\n";
int howbad = 10;
printf(outfile, "\n--------\n");
//myout();
/* then i realized that i can't send the arguments to fn:PRINTs */
printf(outfile, "%s %i",bigfoot, howbad); /* error here! I can't send bigfoot and howbad*/
system("pause");
return 0;
}
I have done it in COUT(caps, the commented part for the code above) . But I want to use normal std::cout, so how can I override it. And it should work for both sting and variables like
int i = 5;
cout << "Hello world" << i <<endl;
Or are there anyway to capture stdout data, so that they can be easily written into file and console as well.
If you have another stream buffer, you can just replace std::cout's:
std::cout.rdbuf(some_other_rdbuf);
See http://en.cppreference.com/w/cpp/io/basic_ios/rdbuf.
You can swap the underlying buffers. Here is that done facilitated through RAII.
#include <streambuf>
class buffer_restore
{
std::ostream& os;
std::streambuf* buf;
public:
buffer_restore(std::ostream& os) : os(os), buf(os.rdbuf())
{ }
~buffer_restore()
{
os.rdbuf(buf);
}
};
int main()
{
buffer_restore b(std::cout);
std::ofstream file("file.txt");
std::cout.rdbuf(file.rdbuf());
// ...
}
Overriding the behaviour of std::cout is a really bad idea as other developers will have a hard time understanding that the use of std::cout doesn't behave as usual.
Make your intention clear with a simple class
#include <fstream>
#include <iostream>
class DualStream
{
std::ofstream file_stream;
bool valid_state;
public:
DualStream(const char* filename) // the ofstream needs a path
:
file_stream(filename), // open the file stream
valid_state(file_stream) // set the state of the DualStream according to the state of the ofstream
{
}
explicit operator bool() const
{
return valid_state;
}
template <typename T>
DualStream& operator<<(T&& t) // provide a generic operator<<
{
if ( !valid_state ) // if it previously was in a bad state, don't try anything
{
return *this;
}
if ( !(std::cout << t) ) // to console!
{
valid_state = false;
return *this;
}
if ( !(file_stream << t) ) // to file!
{
valid_state = false;
return *this;
}
return *this;
}
};
// let's test it:
int main()
{
DualStream ds("testfile");
if ( (ds << 1 << "\n" << 2 << "\n") )
{
std::cerr << "all went fine\n";
}
else
{
std::cerr << "bad bad stream\n";
}
}
This provides a clean interface and outputs the same for both the console and the file.
You may want to add a flush method or open the file in append mode.
I assume you have some code using std::cout and printf which you cannot modify, otherwise the most simple way to solve your problem would be to write to a different stream from cout and use fprintf rather than or in conjunction with printf.
By following that approach you could define both a new stream class that actually wrote both to standard output and to a given file, as well as a function that combined calls to both printf and fprintf.
However a much simpler approach is to use the tee program, originally from UNIX, which copies its input both to output and to a given file. With that you could simply call your program in this way:
your_program | tee your_log_file
Answers to this question lead to a few alternative implementations available for Windows. Personally I always install cygwin on my PC's to have UNIX/Linux utilities available.
If i guess correctly you want to log everything that goes to the output also into a file.
What you want is an observer pattern.
Replace all direct logging in your code with calls to a new relay.
The logging relay sends your messages to the observers.
One of your observers loggs the message to the screen.
The other one loggs to the file.
Avoid making your relay a singleton if possible.
This suggestion only works if you can edit all of your source files.
std::cout writes to stdout file you can do the following on Linux and Windows
#include <stdio.h>
#include <iostream>
int main()
{
freopen("test.txt", "w", stdout);
std::cout << "Hello strange stdout\n";
}
to change it back use the following taken from here
#include <stdio.h>
#include <stdlib.h>
void main(void)
{
FILE *stream ;
if((stream = freopen("file.txt", "w", stdout)) == NULL)
exit(-1);
printf("this is stdout output\n");
stream = freopen("CON", "w", stdout);
printf("And now back to the console once again\n");
}
Note: The latter is windows only
cout is normally implemented as an object instance so you can't override it in the way that you would overload / override a function or a class.
Your best bet is not to fight that - yes you could build a my_cout and #define cout my_cout but that would make your code obtuse.
For readability I'd leave cout as it is. It's a standard and everyone knows what it can and can't do.
Try using a macro - something like this (you'll need to add the includes) :
#define MY_COUT(theos,printThis) { cout << printThis ; theos << printThis; }
void test()
{
ofstream myos;
myos.open("testfile", ios::trunc|ios::out);
int i = 7;
MY_COUT(myos, "try this numbers" << i << i + 1 << endl);
myos.close()
}
There's already a Boost class for this: tee
Related
#include <cstddef>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
//read the lines from the piped file using cin
string response;
int i = 0;
while (getline(cin, response)) {
//if the response is empty, stop
if (response.empty()) {
break;
}
//Write each odd line (1,3, etc..) to stderr (cerr)
//Write each even line (2,4. etc..) to stdout (cout)
if (i % 2 != 1) { //send odd to stderr
cerr << "err: " << response << endl;
}
else { //send even to stdout
cout << "out: " << response << endl;
}
i++;
}
return 0;
}
I want to redirect stderr to /dev/null, how would I go about doing so? I'm new to C++ and trying to learn by practicing, however, I'm not easily able to find an answer that fits my existing program.
Besides the excellent commentary above, it is pretty easy to make a “null” streambuf sink in C++.
#include <iostream>
struct null_streambuf: public std::streambuf
{
using int_type = std::streambuf::int_type;
using traits = std::streambuf::traits_type;
virtual int_type overflow( int_type value ) override
{
return value;
}
};
To use it, just set the rdbuf:
int main()
{
std::cerr.rdbuf( new null_streambuf );
std::cerr << "Does not print!\n";
}
If you wish to be able to turn it off and on, you will have to remember the original and restore it, not forgetting to delete the new null_streambuf.
int main()
{
std::cerr << "Prints!\n";
auto original_cerr_streambuf = std::cerr.rdbuf( new null_streambuf );
std::cerr << "Does not print.\n";
delete std::cerr.rdbuf( original_cerr_streambuf );
std::cerr << "Prints again!\n";
}
This does have the objective effect of being compiled to code, which I suspect is the advantage you are looking for: the ability to dynamically enable and disable diagnostic output.
This is, however, the usual function of a debug build, where you use the DEBUG macro to decide whether or not to compile something (such as error output operations) into the final executable.
Keep in mind that this does not disable output on standard error via other means, but only through cerr.
In my program I use an external function which generates output to me and I don't want it not to be generated by that function alone,
it's possible?
int main()
{
int a;
//I don't want the output of this function
a = function();
//now i want output
cout << "the result is : " << a;
}
Is it possible?
EDIT:
The function is in an external library.
Using only standard C++ where no dup-like functions exist, you could open a temporary std::FILE and std::swap with stdout.
#include <cerrno>
#include <cstring>
#include <cstdio>
#include <fstream>
#include <iostream>
#include <iterator>
#include <string>
#include <sstream>
// extern "C" int function(); // an assumption
// A helper class to temporarilly redirect the output to stdout to a file and to read
// the content of the file afterwards.
class BufferStdout {
public:
// the collector string is used for collecting the output to stdout
BufferStdout (std::string& collector) :
m_collector(collector),
fp(std::fopen("output.txt", "w"))
{
if(fp == nullptr) throw std::runtime_error(std::strerror(errno));
std::swap(stdout, fp); // swap stdout and the temp file
}
~BufferStdout () {
std::swap(stdout, fp); // swap back
std::fclose(fp);
// read the content of the temp file into m_collector
if(std::ifstream is("output.txt"); is) {
m_collector.append(std::istreambuf_iterator<char>(is),
std::istreambuf_iterator<char>{});
}
std::remove("output.txt"); // cleanup
}
private:
std::string& m_collector;
std::FILE* fp;
};
int main() {
std::string collector; // the string that will contain the output from function()
int a;
{
BufferStdout foo(collector);
a = function();
}
std::cout << "the result is : " << a << '\n';
std::cout << "Collected from function():\n";
std::cout << collector << '\n';
}
Yes it is generally possible but a bit complicated, a similar question is in Suppress output to cout from linked library
In addition to you can redirect stdout before invoking the shared library function and then redirect it again after the use of the shared library function in the however this is also a suboptimal solution. Best solution would be to adapt the shared library
// Cpp program to redirect cout to a file
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
fstream file;
file.open("cout.txt", ios::out);
string line;
// Backup streambuffers of cout
streambuf* stream_buffer_cout = cout.rdbuf();
streambuf* stream_buffer_cin = cin.rdbuf();
// Get the streambuffer of the file
streambuf* stream_buffer_file = file.rdbuf();
// Redirect cout to file
cout.rdbuf(stream_buffer_file);
cout << "This line written to file" << endl;
// Redirect cout back to screen
cout.rdbuf(stream_buffer_cout);
cout << "This line is written to screen" << endl;
file.close();
return 0;
}
Note: The above steps can be condensed into a single step
auto cout_buf = cout.rdbuf(file.rdbuf())
// sets couts streambuffer and returns the old
streambuffer back to cout_buf
source : https://www.geeksforgeeks.org/io-redirection-c/
use
fclose(stdout);
with this function you will suppress any printf inside your libraries.
Of course you can not print other stuff inside your software.
Context:
I'm editing a small piece of a large program. This large program is controlling std::cout and rerouting it so that a basic piece of code like:
std::cout << "I want to see the light of the terminal!" << std::endl;
Does not display anything to the user.
Question:
How can I get something to print directly to the terminal when my standard output/error is being rerouted? (If possible)
Other notes:
I realize that I could edit the larger program, but I'm looking to use this printout for some early diagnostics before more fully integrating my code into the program. Having to mess with how the program routes the output would really extend the development cycle.
I am also currently writing to a file as a workaround but that's slightly less desirable and frankly I would like to know how to do this in the future.
I think you can do it following these steps:
Save the redirected buffer
Change buffer to console
Get your job done
Again set buffer to the saved buffer in step 1
For example
#include <sstream>
#include <iostream>
void print_to_console() {
std::cout << "Hello from print_to_console()" << std::endl;
}
void foo(){
std::cout<<"hello world"<<std::endl;
print_to_console(); // this could be printed from anything
}
int main()
{
std::stringstream ss;
//change the underlying buffer and save the old buffer
auto old_buf = std::cout.rdbuf(ss.rdbuf());
foo(); //all the std::cout goes to ss
std::cout.rdbuf(old_buf); //reset
std::cout << "<redirected-output>\n"
<< ss.str()
<< "</redirected-output>" << std::endl;
}
I haven't tested it. I took the idea and example from this accepted answer.
For convenience, you can just write a function to print in console. This function will take care of the redirection and printing.
Write to stdout and read from stdin (both are FILE descriptors).
You can wrap them in stream classes if you wish.. IE: Using streambuf and iostreamto get the same functionality as cout.
#include <iostream>
int main(int argc, const char * argv[]) {
const char* data = "DATA TO PRINT";
fwrite(data, strlen(data), sizeof(char), stdout);
return 0;
}
Small example:
#include <iostream>
class stream : public std::streambuf
{
private:
int_type overflow(int_type c = traits_type::eof());
public:
stream() {}
virtual ~stream() {}
stream(const stream& other) = delete;
stream& operator = (const stream& other) = delete;
};
stream::int_type stream::overflow(stream::int_type c)
{
if (c != traits_type::eof())
{
fwrite(&c, 1, sizeof(c), stdout);
}
return c;
}
class mcout : public std::ostream
{
public:
mcout() : std::ostream(0), sbuf() {init(&sbuf);}
virtual ~mcout() {}
private:
stream sbuf;
} mcout;
int main(int argc, const char * argv[]) {
mcout << "HELLO\n";
return 0;
}
How to determine weather ostream is a file or a console stream. In the following program I want to print "Hello file!" while writing to a file and "Hello console!" while writing to console. What condition should I specify at line 17?
#include <fstream>
#include<iostream>
#include <string>
using namespace std;
class A{
public:
A(string msg):_str(msg){}
string str()const {return _str;};
private:
string _str;
};
ostream & operator << (ostream & os, const A & a)
{
if (os is ofstream) //this is line 17
os << "Hello file! " << a.str() << endl;
else
os << "Hello console! " << a.str() << endl;
return os;
}
int main()
{
A a("message");
ofstream ofile("test.txt");
if (!ofile)
cerr << "Unable to open file";
else
ofile << a; // "Hello file"
cout << a << endl; // "Hello console"
}
Maybe not pretty, but
std::streambuf const * coutbuf = std::cout.rdbuf();
std::streambuf const * cerrbuf = std::cerr.rdbuf();
ostream & operator << (ostream & os, const A & a)
{
std::streambuf const * osbuf = os.rdbuf();
if ( osbuf == coutbuf || osbuf == cerrbuf )
os << "Hello console! " << a.str() << endl;
else
os << "Hello file! " << a.str() << endl;
return os;
}
We could use &os == &std::cout, but the Standard output might be redirected to file, so I think it is better to use the streambuf object instead. (See this answer for better understanding as to how the redirection works, and why comparing streambuf solves the problem safely! )
You could (ab)use tellp(), which returns -1 if the stream does not have a position:
bool isConsoleStream(ostream const& stream)
{
return stream.tellp() == -1;
}
Of course, there could be other streams that return -1 for this function, so use with caution.
There is no portable means. Under Unix, you can do:
if ( (&os == &std::cout && isatty( STDOUT ))
|| (&os == &std::cerr && isatty( STDERR ))
|| (&os == &std::clog && isatty( STDERR )) ) }
// is a terminal...
}
Under Windows, the isatty becomes _isatty, and I'm not sure
that the macros exist (but I suspect that they do).
Of course, this supposes that you don't do things to confuse it
in your code. Something like:
std::ostream s( std::cout.rdbuf() );
for example, or:
std::cout.rdbuf( &someFileBuf );
Or even:
std::ofstream s( "/dev/tty" ); // (or "CONS" under Windows).
But it's about as close as you can get without the actual fd
from the filebuf.
One is a ofstream and the other is a ostream. Just have two methods.
#include <iostream>
#include <string>
#include <fstream>
class A {
std::string s;
public:
A(const std::string& s) : s(s){}
std::string str() const {return s;}
};
ostream & operator << (std::ostream & os, const A & a)
{
return os << "console: " << a.str() << std::endl;
}
ofstream & operator << (std::ofstream & os, const A & a)
{
return os << "file: " << a.str() << std::endl;
}
int main()
{
A a("hello world");
std::cout << a << endl;
}
This works on Visual Studio 2012
if (typeid(os) == typeid(ofstream)) //this is line 17
But an ostream could be something that isn't an ofstream or the console so you'd have to be careful.
Function to check if a C++ character stream is connected to a terminal/console/tty.
Ideally, we would use the file descriptor under-laying the stream buffer of the C++ stdio stream (cin, cout, cerr or clog).
However, there is no way to retrieve the under-laying file descriptor.
So, we use the fact that at program start-up the stdio stream buffers are connected to the program's standard input and output.
This function only works under the following conditions:
The stream buffers of the start-up C++ stdio streams must not change.
Because the addresses of the stream buffers of the start-up C++ stdio streams are used as identifiers.
For instance by deleting them and then allocating a new stream buffer that has the same address as one of these stream buffers of the start-up C++ stdio streams.
The program's stdio must not change after program start-up.
Because the TTY statuses of the stdio stream buffers are stored at program start-up.
For instance if at start-up the std. out is connected to a terminal and later it is redirected to a pipe or file by something external to the program.
[Instead of storing the TTY statuses at start-up you could retrieve them at run-time, but then you must make sure that your program (and all libraries it uses) does not change the stdio file descriptors (0, 1 and 2). Rember that the stdio stream buffers most likely use other (duplicate) file descriptors.]
Code:
#include <iostream>
extern "C" {
#ifdef _WIN32
# include <io.h> // for: _isatty()
#else
# include <unistd.h> // for: isatty()
#endif
}
// Stdio file descriptors.
#ifndef STDIN_FILENO
# define STDIN_FILENO 0
# define STDOUT_FILENO 1
# define STDERR_FILENO 2
#endif
// Store start-up addresses of C++ stdio stream buffers as identifiers.
// These addresses differ per process and must be statically linked in.
// Assume that the stream buffers at these stored addresses
// are always connected to their underlaying stdio files.
static const streambuf* const StdioBufs[] = {
std::cin.rdbuf(), std::cout.rdbuf(), std::cerr.rdbuf(), std::clog.rdbuf()
};
static const wstreambuf* const StdioWBufs[sizeof(StdioBufs)/sizeof(StdioBufs[0])] = {
std::wcin.rdbuf(), std::wcout.rdbuf(), std::wcerr.rdbuf(), std::wclog.rdbuf()
};
// Store start-up terminal/TTY statuses of C++ stdio stream buffers.
// These statuses differ per process and must be statically linked in.
// Assume that the statuses don't change during the process life-time.
static const bool StdioTtys[sizeof(StdioBufs)/sizeof(StdioBufs[0])] = {
#ifdef _WIN32
_isatty(STDIN_FILENO), _isatty(STDOUT_FILENO), _isatty(STDERR_FILENO), _isatty(STDERR_FILENO)
#else
isatty(STDIN_FILENO), isatty(STDOUT_FILENO), isatty(STDERR_FILENO), isatty(STDERR_FILENO)
#endif
};
// Is a Terminal/Console/TTY connected to the C++ stream?
// Use on C++ stdio chararacter streams: cin, cout, cerr and clog.
bool isTTY(const ios& strm)
{
for(unsigned int i = 0; i < sizeof(StdioBufs)/sizeof(StdioBufs[0]); ++i) {
if(strm.rdbuf() == StdioBufs[i])
return StdioTtys[i];
}
return false;
}
// Is a Terminal/Console/TTY connected to the C++ stream?
// Use on C++ stdio wide-chararacter streams: wcin, wcout, wcerr and wclog.
bool isTTY(const wios& strm)
{
for(unsigned int i = 0; i < sizeof(StdioWBufs)/sizeof(StdioWBufs[0]); ++i) {
if(strm.rdbuf() == StdioWBufs[i])
return StdioTtys[i];
}
return false;
}
Note: I've only tested it on Linux.
Is there a way to define/undefine debug messages using std::cout whenever inside a program?
I am aware that there are such things such as #define, #ifndef, but I was thinking is there a cleaner way to having a variable say:
# debug ON
That prints all of my debug data (using std::cout). Consequently, we'll have code like this for debug:
#ifndef DEBUG
// do something useful
#endif
I find the above code cumbersome when you write 100s of debug code.
Thanks!
Carlo
#ifdef DEBUG
#define DEBUG_MSG(str) do { std::cout << str << std::endl; } while( false )
#else
#define DEBUG_MSG(str) do { } while ( false )
#endif
int main()
{
DEBUG_MSG("Hello" << ' ' << "World!" << 1 );
return 0;
}
Some logging libraries are pretty heavy weight unless you have complex logging needs. Here's something I just knocked together. Needs a little testing but might meet your requirements:
#include <cstdio>
#include <cstdarg>
class CLog
{
public:
enum { All=0, Debug, Info, Warning, Error, Fatal, None };
static void Write(int nLevel, const char *szFormat, ...);
static void SetLevel(int nLevel);
protected:
static void CheckInit();
static void Init();
private:
CLog();
static bool m_bInitialised;
static int m_nLevel;
};
bool CLog::m_bInitialised;
int CLog::m_nLevel;
void CLog::Write(int nLevel, const char *szFormat, ...)
{
CheckInit();
if (nLevel >= m_nLevel)
{
va_list args;
va_start(args, szFormat);
vprintf(szFormat, args);
va_end(args);
}
}
void CLog::SetLevel(int nLevel)
{
m_nLevel = nLevel;
m_bInitialised = true;
}
void CLog::CheckInit()
{
if (!m_bInitialised)
{
Init();
}
}
void CLog::Init()
{
int nDfltLevel(CLog::All);
// Retrieve your level from an environment variable,
// registry entry or wherecer
SetLevel(nDfltLevel);
}
int main()
{
CLog::Write(CLog::Debug, "testing 1 2 3");
return 0;
}
Probably not. I would recommend using a logging library. I'm not sure what the best option is for C++ anymore, but I've used log4cpp in the past and found it pretty good.
EDIT: I assume on the fly means # runtime. If you just need it to be a compile time flag, then Gianni's answer is probably easiest to implement. Logging libraries give you a lot of flexibility and allow reconfiguration # runtime though.
Another simple solution, involves opening a std::ostream reference to cout in debug mode, and /dev/null in non-debug mode, like so:
In debug.h:
extern std::ostream &dout;
In debug.c
#ifdef DEBUG
std::ostream &dout = cout;
#else
std::ofstream dev_null("/dev/null");
std::ostream &dout = dev_null;
#endif
And then:
dout << "This is a debugging message";
Of course, this would only work on any system where /dev/null points to a null device. Since the dout reference is global here, it would much like cout. In this way, you can point the same stream to multiple output streams, for example to a log file, depending of the value of debug flags, etc.
Although the question is old, and there are some good answers, i want to post also a solution to this. It is like Giannis approach but different. And also, i used std::cerr instead of std::cout, but you can change this really quick.
#include <iostream>
#ifdef DEBUG
# define DEBUG_LOG std::cerr
#else
class log_disabled_output {};
static log_disabled_output log_disabled_output_instance;
template<typename T>
log_disabled_output& operator << (log_disabled_output& any, T const& thing) { return any; }
// std::endl simple, quick and dirty
log_disabled_output& operator << (log_disabled_output& any, std::ostream&(*)(std::ostream&)) { return any; }
# define DEBUG_LOG log_disabled_output_instance
#endif
int main() {
int x=0x12345678;
DEBUG_LOG << "my message " << x << " " << "\n more information" << std::endl;
};
Now you can use it just like a output stream.
(Note: iostream is only included if cerr is used. This will reduce the amount of inclusion if you don't have it already included. -edit: not with std::endl support).
If DEBUG is defined cerr is used to print the error. Otherwise the dummy class log_disabled_output is instantiated statically and operator<< is overloaded to any type. The vantage is; If you disable the logging, a clever compiler will notice that there is nothing to do with the stream and optimize the entire "line" away, so you don't have any overhead if DEBUG is disabled.
I was trying to do the same thing. After some research, I developed the following, and it seems to work. Please comment if you see anything wrong.
ostream DbgMsg(NULL);
enum {
DBGMSG_NONE,
DBGMSG_DEFAULT,
DBGMSG_VERBOSE
} DbgLvl = DBGMSG_DEFAULT;
ostream &DbgMsgDefault(ostream &stream) {
return (DbgLvl>=DBGMSG_DEFAULT) ? cout : stream;
}
ostream &DbgMsgVerbose(ostream &stream) {
return (DbgLvl>=DBGMSG_VERBOSE) ? cout : stream;
}
void main() {
DbgMsg<<DbgMsgDefault<<"default:default"<<endl;
DbgMsg<<DbgMsgVerbose<<"default:verbose"<<endl;
DbgLvl = DBGMSG_NONE;
DbgMsg<<DbgMsgDefault<<"none:default"<<endl;
}
A clean thing to do would be to use cerr.
"cerr" acts essentially as "cout", but always flushes the output (useful for debugging, by the way). If you need to remove all the messages, you can comment out all the cerr messages with a simple find-and-replace (cerr into //cerr).
There are probably even better ways to use cerr and to desactivate it cleanly (which writes into a special stream, the error stream, hence the name).
I hope this helps.
This is what I used (worked with VC++) - here "##" is used for concatennation
#ifdef DEBUG
#define pout cout
#else
#define pout / ## / cout
#endif
For other compilers use this :
#ifdef DEBUG
#define pout cout
#else
#define pout 0 && cout
#endif
Usage :
pout << "hello world" << endl;
I was looking for similar example and sharing my example below:
#include <iostream>
enum debug_option
{
DEBUG_DISABLE,
DEBUG_ENABLE
};
class debug
{
public:
debug_option debug_state;
debug() : debug_state(DEBUG_ENABLE) {} // constr
debug(debug_option state) : debug_state(state) {} // constr
template<typename T>
debug & operator<< (T input)
{
if (this->debug_state == DEBUG_ENABLE)
std::cout << input;
return *this;
}
};
int main()
{
debug log, log_lev2(DEBUG_DISABLE);
log << "print 1..\n" << 55 << " over\n";
log.debug_state = DEBUG_DISABLE;
log << "print 2..\n" << 3 << "over\n";
log_lev2 << "print 3..\n" << 4 << "over\n";
log_lev2.debug_state = DEBUG_ENABLE;
log_lev2 << "print 5..\n";
std::cout << "std::cout << print..\n";
return 0;
}
Better suggestions are always welcome.