C++ 定制C++;cout类-输出到控制台和日志文件
我正在编写一个程序,如果你绝望,可以大量使用“cout:C++ 定制C++;cout类-输出到控制台和日志文件,c++,console,stdout,cout,C++,Console,Stdout,Cout,我正在编写一个程序,如果你绝望,可以大量使用“cout: #define protected public #include <iostream> #undef protected #定义受保护的公共 #包括 #未定义保护 这是一个严重的攻击,但它通常是有效的。您可以使用一个包装器类来实现这一点,比如 #include <iostream> #include <fstream> ... class streamoutput { std::ofs
#define protected public
#include <iostream>
#undef protected
#定义受保护的公共
#包括
#未定义保护
这是一个严重的攻击,但它通常是有效的。您可以使用一个包装器类来实现这一点,比如
#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");
#包括
#包括
...
类流输出
{
std::流文件输出;
公众:
streamoutput(字符*文件名){
fileoutput.open(文件名);
}
~streamoutput(){
fileoutput.close();
}
模板streamoutput&操作符是为此创建的
#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;
}
sync
调用可以替换为pubsync
。至于overflow
调用,我认为这可能是一个输入错误。因为它看起来应该是对sputc
的调用,您可以做的是用指向std::streambuf
的指针捕获std::cout.rdbuf()
,
然后,我认为您应该能够将所有输出写入std::cout
到某个文件。很抱歉这么晚才对此进行预热,但这应该是一个基于Dietmar Kühl在Google Group上的解决方案,将cout重定向到teebuffer的解决方案
用法很简单
GetSetLog log("myfile.log");
在对象“日志”的生命周期内,所有内容都将写入cout/cerr和file
这很容易扩展到其他流
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 ;
}
重复,我认为:(它同时包含一个Boost和非Boost解决方案。)聪明而简单的解决方案:这对我来说很好-不幸的是,我被要求不将Boost作为此应用程序的一部分。管理,非技术性决策。那么-你如何在just std中做到这一点?@Jason看起来还有一些其他答案不使用Boost。祝你好运。这将适用于我们编写的代码,我们可以修改我们的#include行。但这对第三方代码不起作用,第三方代码也必须使用#include,但由于许可,我们不能修改。然后您可以只修改iostream文件!没有lisence可以阻止您这样做!但是如果您有一个完全不同的预编译代码,但您也可以编写一个包装程序运行您的和执行所有控制台的gram为您工作。虽然这需要更多的努力!将“sync”更改为“pubsync”编译。但将“overflow”更改为“putc”失败。错误C2039“putc”不是std::basic_streambufSorry的成员,这是一个输入错误。在我的回答中,我将其更正为sputc
。在我们的情况下(无法使用Boost,无法修改第三方库),这是最好的解决方案。在这一点上,我非常绝望,甚至接受了一个丑陋的黑客攻击。不幸的是,对于VS2008,它没有帮助。相同的原始错误。
#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 ;
}
#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 ;
}
0 0
1 10
2 20
3 30
4 40
5 50
6 60
7 70
8 80
9 90