Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 定制C++;cout类-输出到控制台和日志文件_C++_Console_Stdout_Cout - Fatal编程技术网

C++ 定制C++;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

我正在编写一个程序,如果你绝望,可以大量使用“cout:

#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