I'm working on a program that makes heavy use of "cout << strSomething;" to log information to the console. I need to modify the program so that all console output goes to both the console AND a file. Although I can modify the "cout <<" in our code, there are several large third party libraries that also use "cout <<"; those libraries cannot be modified due to their licenses - so modifying all references to "cout <<" is not a solution. Also, the use of "wtee.exe" isn't possible due to the manner in which the command lines are executed.
我正在开发一个程序,该程序大量使用“cout < strSomething;”来将信息记录到控制台。我需要修改程序,以便所有控制台输出都同时到达控制台和文件。虽然我可以在我们的代码中修改“cout <<”,但是也有几个大型的第三方库也使用“cout <<”;由于这些库的许可,这些库不能被修改——因此修改对“cout <”的所有引用不是一个解决方案。另外,使用“wtee”。由于命令行被执行的方式是不可能的。
I am using Visual Studio 2008. I've seen the posting at Google Groups: redirect cout to file, which appears to do EXACTLY what I want to do. The only problem is that the code won't compile. I get C2248 errors "cannot access protected member" on the ->overflow() and ->sync() method calls.
我正在使用Visual Studio 2008。我看到了谷歌组的帖子:重定向cout到文件,这似乎正是我想做的。唯一的问题是代码不能编译。在->overflow()和->sync()方法调用中,我得到C2248错误“无法访问受保护成员”。
Would anyone know how to get this code to compile? Or an alternate way of redirecting cout to both console and file simultaneously?
有人知道如何编译这段代码吗?还是同时将cout重定向到控制台和文件的另一种方法?
6 个解决方案
#1
1
The sync
calls can be replaced with pubsync
. As for the overflow
call I think that may be a typo. as it looks as if it should be a call to sputc
.
同步调用可以被pubsync代替。至于溢流电话,我想可能是打错了。看起来好像是打给sputc的电话。
#2
12
The boost::iostreams::tee_device
is made for this
这个boost::::iostreams: tee_device就是为此而设计的
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/tee.hpp>
#include <fstream>
#include <iostream>
int
main()
{
typedef boost::iostreams::tee_device<std::ostream, std::ofstream> Tee;
typedef boost::iostreams::stream<Tee> TeeStream;
std::ofstream file( "foo.out" );
Tee tee( std::cout, file );
TeeStream both( tee );
both << "this goes to both std::cout and foo.out" << std::endl;
return 0;
}
sample invocation:
示例调用:
samm$ ./a.out
this goes to both std::cout and foo.out
samm$ cat foo.out
this goes to both std::cout and foo.out
samm$
#3
2
if you're desperate:
如果你是绝望:
#define protected public
#include <iostream>
#undef protected
this is a gross hack, but it usually works.
这是一种粗制滥造的手法,但通常管用。
#4
1
What you can do is capture the std::cout.rdbuf()
with a pointer to std::streambuf
, then i think you should be able to write all the outputs to std::cout
to some file.
您可以使用指向std::streambuf的指针捕获std::cout.rdbuf(),然后我认为您应该能够将所有输出写到std::cout到某个文件。
#5
0
you can just use a wrapper class to do so, somthing like this
您可以使用包装器类来实现这一点,类似这样的东西
#include <iostream>
#include <fstream>
...
class streamoutput
{
std::ofstream fileoutput;
public:
streamoutput(char*filename){
fileoutput.open(filename);
}
~streamoutput(){
fileoutput.close();
}
template<class TOut> streamoutput& operator <<(const TOut& data)
{
fileoutput << data;
std::cout << data;
return this;
}
};
extern streamoutput cout("logfile.log");
declare cout like that and just change all your #include <iostream>
to include this wrapper (remeber cout is external variable so you have to declere it in one of your source codes too).
像这样声明cout,然后修改所有的#include
#6
0
Sorry to warm this up so late, but this here should be a solution with redirection of cout to a teebuffer based on Dietmar Kühl's solution on Google groups.
很抱歉这么晚才把它热身,但这应该是一个解决方案,将cout重定向到teebuffer,基于Dietmar Kuhl在谷歌组上的解决方案。
Usage is simply
使用很简单
GetSetLog log("myfile.log");
During the lifetime of the object "log" everything will be written to both cout/cerr and file
在对象“日志”的生命周期中,所有内容都将写入cout/cerr和文件
https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx
https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx
#1
1
The sync
calls can be replaced with pubsync
. As for the overflow
call I think that may be a typo. as it looks as if it should be a call to sputc
.
同步调用可以被pubsync代替。至于溢流电话,我想可能是打错了。看起来好像是打给sputc的电话。
#2
12
The boost::iostreams::tee_device
is made for this
这个boost::::iostreams: tee_device就是为此而设计的
#include <boost/iostreams/stream.hpp>
#include <boost/iostreams/tee.hpp>
#include <fstream>
#include <iostream>
int
main()
{
typedef boost::iostreams::tee_device<std::ostream, std::ofstream> Tee;
typedef boost::iostreams::stream<Tee> TeeStream;
std::ofstream file( "foo.out" );
Tee tee( std::cout, file );
TeeStream both( tee );
both << "this goes to both std::cout and foo.out" << std::endl;
return 0;
}
sample invocation:
示例调用:
samm$ ./a.out
this goes to both std::cout and foo.out
samm$ cat foo.out
this goes to both std::cout and foo.out
samm$
#3
2
if you're desperate:
如果你是绝望:
#define protected public
#include <iostream>
#undef protected
this is a gross hack, but it usually works.
这是一种粗制滥造的手法,但通常管用。
#4
1
What you can do is capture the std::cout.rdbuf()
with a pointer to std::streambuf
, then i think you should be able to write all the outputs to std::cout
to some file.
您可以使用指向std::streambuf的指针捕获std::cout.rdbuf(),然后我认为您应该能够将所有输出写到std::cout到某个文件。
#5
0
you can just use a wrapper class to do so, somthing like this
您可以使用包装器类来实现这一点,类似这样的东西
#include <iostream>
#include <fstream>
...
class streamoutput
{
std::ofstream fileoutput;
public:
streamoutput(char*filename){
fileoutput.open(filename);
}
~streamoutput(){
fileoutput.close();
}
template<class TOut> streamoutput& operator <<(const TOut& data)
{
fileoutput << data;
std::cout << data;
return this;
}
};
extern streamoutput cout("logfile.log");
declare cout like that and just change all your #include <iostream>
to include this wrapper (remeber cout is external variable so you have to declere it in one of your source codes too).
像这样声明cout,然后修改所有的#include
#6
0
Sorry to warm this up so late, but this here should be a solution with redirection of cout to a teebuffer based on Dietmar Kühl's solution on Google groups.
很抱歉这么晚才把它热身,但这应该是一个解决方案,将cout重定向到teebuffer,基于Dietmar Kuhl在谷歌组上的解决方案。
Usage is simply
使用很简单
GetSetLog log("myfile.log");
During the lifetime of the object "log" everything will be written to both cout/cerr and file
在对象“日志”的生命周期中,所有内容都将写入cout/cerr和文件
https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx
https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx