我正在制作一个大量使用“cout<< strSomething”的程序。将信息记录到控制台。我需要修改程序,以便所有控制台输出都转到控制台和文件。虽然我可以修改“cout<<”在我们的代码中,有几个大的第三方库也使用“cout<<”;这些库由于其许可证而无法修改 - 因此修改所有对“cout<<”的引用不是解决方案。此外,由于命令行的执行方式,无法使用“wtee.exe”。
我正在使用Visual Studio 2008.我在Google Groups: redirect cout to file看到了帖子,这似乎完全符合我的要求。唯一的问题是代码不会编译。我在 - > overflow()和 - > sync()方法调用上得到C2248错误“无法访问受保护的成员”。
有谁知道如何编译这段代码?或者将cout同时重定向到控制台和文件的另一种方法是什么?
答案 0 :(得分:12)
为此
制作了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;
}
示例调用:
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$
答案 1 :(得分:2)
如果你绝望了:
#define protected public
#include <iostream>
#undef protected
这是一个严重的黑客行为,但它通常有效。
答案 2 :(得分:2)
这很容易扩展到其他流。
OstreamFork.hpp-同时将数据分配到2个流
#include <iomanip>
#include <fstream>
#include <iostream>
using namespace std ;
class ostreamFork // Write same data to two ostreams
{
public:
ostream& os1 ;
ostream& os2 ;
ostreamFork( ostream& os_one , ostream& os_two )
: os1( os_one ) ,
os2( os_two )
{}
} ;
// For data: int, long , ...
template <class Data>
ostreamFork& operator<<( ostreamFork& osf , Data d )
{
osf.os1 << d ;
osf.os2 << d ;
return osf ;
}
// For manipulators: endl, flush
ostreamFork& operator<<( ostreamFork& osf , ostream& (*f)(ostream&) )
{
osf.os1 << f ;
osf.os2 << f ;
return osf ;
}
// For setw() , ...
template<class ManipData>
ostreamFork& operator<<( ostreamFork& osf , ostream& (*f)(ostream&, ManipData ) )
{
osf.os1 << f ;
osf.os2 << f ;
return osf ;
}
TestOstreamFork.cpp:
#include "stdafx.h"
#include <fstream>
using namespace std ;
#include "ostreamFork.hpp"
int main(int argc, char* argv[])
{
ofstream file( "test2.txt" ) ;
ostreamFork osf( file , cout ) ;
for ( int i = 0 ; i < 10 ; i++ )
{
osf << i << setw(10) << " " << 10*i << endl ;
}
return 0 ;
}
输出到cout和test2.txt:
0 0
1 10
2 20
3 30
4 40
5 50
6 60
7 70
8 80
9 90
答案 3 :(得分:1)
sync
来电可以替换为pubsync
。至于overflow
电话,我认为这可能是一个错字。因为看起来它应该是对sputc
的调用。
答案 4 :(得分:1)
您可以做的是使用指向std::cout.rdbuf()
的指针捕获std::streambuf
,
那么我认为你应该能够将std::cout
的所有输出写入某个文件。
答案 5 :(得分:0)
你可以使用包装类来做到这一点,就像这样
#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");
声明这样的cout,只需更改所有#include <iostream>
以包含此包装器(记住cout是外部变量,因此您必须在其中一个源代码中对其进行删除)。
答案 6 :(得分:0)
很抱歉这么晚才热身,但这里应该是一个解决方案,根据DietmarKühl的Google群组解决方案将cout重定向到teebuffer。
用法很简单
GetSetLog log("myfile.log");
在对象“log”的生命周期中,所有内容都将写入cout / cerr和file
https://sourceforge.net/p/getset/code/ci/master/tree/GetSet/GetSetLog.hxx