2014-11-30 5 views
5

콘솔과 파일에 동일한 데이터를 인쇄해야하는 코드를 작성하고 있습니다. 일반적인 출력 스트림 객체를 채우고 cout을 사용하여 콘솔에 표시하고 fstream 및 iostream 라이브러리를 사용하여 파일로 내보내는 방법이 있습니까?콘솔 및 C++의 파일에 인쇄 할 공통 출력 스트림 객체를 만드는 방법이 있습니까?

+3

사용하십시오 ['부스트 : IOSTREAMS :: tee_device'] (http://www.boost.org/doc/libs/ : 예를 들어

, 여기에이 방법의 간단한 구현 1_39_0/libs/iostreams/doc/functions/tee.html). – 0x499602D2

+0

호출 환경에서이 작업을 수행하는 것이 좋습니다. –

답변

6

확실히. 내부적으로 쓰는 다른 스트림 버퍼에 저장하는 적절한 스트림 버퍼를 만들 것입니다. 이 스트림 버퍼를 사용하면 쓰고있는 std::ostream을 생성 할 수 있습니다.

#include <streambuf> 
#include <ostream> 

class teebuf 
    : public std::streambuf 
{ 
    std::streambuf* sb1_; 
    std::streambuf* sb2_; 

    int overflow(int c) { 
     typedef std::streambuf::traits_type traits; 
     bool rc(true); 
     if (!traits::eq_int_type(traits::eof(), c)) { 
      traits::eq_int_type(this->sb1_->sputc(c), traits::eof()) 
       && (rc = false); 
      traits::eq_int_type(this->sb2_->sputc(c), traits::eof()) 
       && (rc = false); 
     } 
     return rc? traits::not_eof(c): traits::eof(); 
    } 
    int sync() { 
     bool rc(false); 
     this->sb1_->pubsync() != -1 || (rc = false); 
     this->sb2_->pubsync() != -1 || (rc = false); 
     return rc? -1: 0; 
    } 
public: 
    teebuf(std::streambuf* sb1, std::streambuf* sb2) 
     : sb1_(sb1), sb2_(sb2) { 
    } 
}; 

class oteestream 
    : private virtual teebuf 
    , public std::ostream { 
public: 
    oteestream(std::ostream& out1, std::ostream& out2) 
     : teebuf(out1.rdbuf(), out2.rdbuf()) 
     , std::ostream(this) { 
     this->init(this); 
    } 
}; 

#include <fstream> 
#include <iostream> 

int main() 
{ 
    std::ofstream fout("tee.txt"); 
    oteestream tee(fout, std::cout); 
    tee << "hello, world!\n"; 
} 
+1

여기에 사용자 정의 스트림 버퍼가 과도 할 수도 있습니다. 'stringstream'에 저장하고 두 번 출력하면 충분할 것입니다. 어쨌든, 좋은 것. (그 코드는 주변에 놓여 있었습니까?) – Deduplicator

+1

@Deduplicator : 예, 사용하기 좋은 PITA와 사용할 수있는 적절한 솔루션이 있습니다. 스트림 버퍼를'std :: ostream'으로 래핑하면 티 스트림 버퍼가 사용하기에 꽤 좋다. ... 그리고 네, 저는이 코드가 주위에 거짓말을했습니다 : 나는 _that_ 빠른 입력하지 않고 있습니다 :-) –