2012-12-20 6 views
12

freopen()을 사용하여 텍스트 파일과 화면으로 인쇄하려하지만 인쇄 만하고 있습니다.freopen()을 사용하여 파일 및 화면으로 인쇄

프로그램 출력을 파일로 저장하고 화면에 인쇄하는 것이 쉬운 지 궁금합니다. 나는 다른 방식으로이 작업을했기 때문에 모든 문장을 두 번 인쇄해야했습니다. 하나는 파일 용이고 다른 하나는 출력 용입니다.

참고 : 저는 C++을 처음 접했고 다음 학기 수업을 위해 배우려고하기 때문에 이미 온라인으로 보았으므로이 솔루션에 대한 간단한 답을 찾을 수 없으므로 직접 대답이 필요합니다. ,

$ my-program | tee output.txt 

터미널에 표준 출력에 복사합니다 :

#include<iostream> 
#include<time.h> 
#include<stdlib.h> 
#include<fstream> 

using namespace std; 

void menu(){ 
    cout << "\t********************************************************\n" 
     << "\t* Welcome to slot machine.        *\n" 
     << "\t* Would you like to play? (1 to play, 2 not to play) *\n" 
     << "\t********************************************************\n\n"; 
    return; 
} 

void update(int arr[], int &token) { 
    if (arr[0]==arr[1] && arr[1]==arr[2]) { 
     token+=4; 
     cout << "You win\n\n"; 
    } else if (arr[0]==arr[1] || arr[1]==arr[2] || arr[0]==arr[2]) { 
     token+=1; 
     cout << "You got two out of three\n\n"; 
    } else { 
     token-=1; 
     cout << "You lose\n\n"; 
    } 
} 

int main() { 
    freopen("file.txt", "w", stdout); 
    int x, arr[3], token=4; 
    srand(time(0)); 
    menu(); 
    cin >> x; 
    while(token!=0) { 
     cout << "You have " << token << " tokens\n\n" 
      << "Pull? (1 to pull, 2 not to pull)\n\n"; 
     cin>>x; 
     if(x==1) { 
      for(int i=0; i<3; i++) { 
       arr[i]=1+rand()%10; 
      } 
      cout << "\t\t"; 
      for(int j=0; j<3; j++) { 
       cout << arr[j] << " "; 
      } 
      cout << "\n\n"; 
      update(arr,token); 
     } 
     else{ 
      cout << "OK\n"; 
     } 
    } 
    cin.get(); 
    return 0; 
} 
+0

+1 형식이 적절합니다. –

+1

모든 것을 두 번 써야합니다. freopen (..., stdout)은 stdout의 현재 대상을 freopen()의 첫 번째 인수의 파일 (핸들)로 바꿉니다.C/C++의 파일 (또는 스트림)은 한 곳으로 만 이동할 수 있습니다. 초심자로서, 두 곳으로 출력되는 코드를 작성하는 쉬운 방법이 있는지 확신하지 못합니다. 내가 할 수있는 방법은 한 번에 두 장소에 쓰는 ostream의 변형을 구현하는 것입니다. 하지만 초보자 용 코딩은 거의 없습니다. –

답변

6

나는 그것을 달성하는 간단한 방법을 모른다. 그러나 나는 이것을 어떻게 든 해결할 수 있었다.

fstream을 사용하면 콘솔에 쓰는 것과 같은 방법으로 파일을 출력 할 수 있습니다.

#include <fstream> 

int main() 
{ 
    std::ofstream f("file.txt"); 
    f << "something"; 
} 

이제 우리가 시작할 수있는 점이 있습니다. 콘솔과 파일로 동시에 출력 할 수있는 방법이 있습니까?

나는 최근에 그 문제를 해결하기 위해 스트림 디멀티플렉서를 작성했습니다 :

#include <vector> 
#include <ostream> 
class stream_demultiplexer 
{ 
private: 
    typedef std::vector<std::ostream*> str_cont; 
    str_cont d; 
public: 
    stream_demultiplexer& put(std::ostream::char_type ch) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (*it)->put(ch); 
     return *this; 
    } 

    stream_demultiplexer& write(const std::ostream::char_type* s, std::streamsize count) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (*it)->write(s, count); 
     return *this; 
    } 

    stream_demultiplexer& flush() 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (*it)->flush(); 
     return *this; 
    } 


    template<typename T> 
    stream_demultiplexer& operator<<(const T& obj) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (**it) << obj; 
     return *this; 
    } 

    stream_demultiplexer& operator<<(std::ios_base& (*func)(std::ios_base&)) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (**it) << func; 
     return *this; 
    } 

    template<typename CharT, typename Traits> 
    stream_demultiplexer& operator<<(std::basic_ios<CharT,Traits>& (*func)(std::basic_ios<CharT,Traits>&)) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (**it) << func; 
     return *this; 
    } 

    stream_demultiplexer& operator<<(std::ostream& (*func)(std::ostream&)) 
    { 
     for(str_cont::iterator it = d.begin(); it != d.end(); ++it) 
      (**it) << func; 
     return *this; 
    } 

    void add_stream(std::ostream& ss) 
    { 
     d.push_back(&ss); 
    } 
}; 

당신은 다음과 같이 사용할 수 있습니다 :

:

stream_demultiplexer spl; 
std::ofstream f("file.txt"); 
spl.add_stream(f); 
spl.add_stream(std::cout); 
spl << 55 << " HELLO WORLD"; 

내 접근 방식은 조종과 포맷되지 않은 출력이 제대로 작동 장점이있다

spl << 76 << " " << std::hex << 76 << std::endl; 
spl.put('a'); 
spl.write("ABCDE", 5); 
+1

도움 주셔서 대단히 감사합니다. 나쁘다면 더 간단한 방법은 아닙니다. – Bob

4

유닉스 같은 환경에서 쉬운 방법은 쉘 명령 tee을 사용하는 것입니다 : 여기

는 내가 지금까지 무엇을 가지고 또한 파일 output.txt에도 적용됩니다. 당신이 코드에서해야 할 경우


, 당신은 모든 operator<<에 두 개 (또는 그 이상)의 ostreams을 전달하는 대신 cout의 자신의 출력 스트림을 사용할 수 있습니다. 이것은 C++의 ostream cout의 기본 파일 인 C 출력 파일을 사용하는 것보다 나에게 더 기분이 좋습니다. 당신이 당신의 freopen을 라인을 교체하는 경우

#include <ostream> 

class Tee { 
    std::ostream &first, &second; 

    template<typename T> friend Tee& operator<< (Tee&, T); 

public: 
    Tee(std::ostream &f, std::ostream &s) : first(f), second(s) {} 
}; 

template <typename T> 
Tee& operator<< (Tee &t, T val) 
{ 
    t.first << val; 
    t.second << val; 
    return t; 
} 

그런 :

std::ofstream outfile("file.txt"); 
Tee tee(std::cout, outfile); 

당신은 tee << 대신 cout << 사용할 수 있습니다.

함수에 tee을 전달하거나 전역 함수로 전달해야합니다.

+0

또한,'tee << endl;을 할 수 없다는 것에주의하십시오. 따라서, 당신은 그 기능을 원한다면' '\ n' '을 사용해야하고'Tee.flush()'를 구현해야합니다. – feetwet