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
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
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()
}
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());
// ...
}
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 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.