2012-12-20 86 views
12

Tôi đang cố gắng sử dụng freopen() để in ra tệp văn bản và màn hình, nhưng tôi chỉ đạt được việc in một tệp.Sử dụng freopen() để in ra tệp và màn hình

Tôi đã tự hỏi liệu có dễ dàng lưu đầu ra chương trình vào một tệp và in nó ra màn hình không? Bởi vì tôi đã làm việc này theo một cách khác, nhưng cuối cùng tôi phải in ra mọi tuyên bố hai lần. Một là cho các tập tin khác chỉ cho đầu ra.

Lưu ý: Tôi mới tham gia C++ và tôi đang cố gắng học nó cho một lớp học tiếp theo để câu trả lời trực tiếp là cần thiết vì tôi đã xem trực tuyến và không thể tìm thấy bất kỳ câu trả lời đơn giản nào cho giải pháp này bên cạnh.

Dưới đây là những gì tôi có cho đến nay:

#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 cho câu hỏi được đặt đúng. –

+1

Bạn sẽ vẫn phải viết mọi thứ hai lần. freopen (..., stdout) sẽ thay thế đích hiện tại của stdout bằng tập tin (handle) của đối số đầu tiên của freopen().Một tệp (hoặc luồng) trong C/C++ chỉ có thể đi đến một nơi. Là người mới bắt đầu, tôi không chắc chắn có cách DỄ DÀNG để viết mã xuất ra hai địa điểm. Cách tôi sẽ làm điều đó là bằng cách thực hiện biến thể của riêng tôi của ostream mà viết đến hai nơi cùng một lúc. Nhưng đó là hầu như không bắt đầu mã hóa. –

Trả lời

6

Tôi không biết cách nào đơn giản để đạt được điều đó, nhưng tôi đã giải quyết được điều này bằng cách nào đó.

Sử dụng fstreams bạn có thể xuất ra tệp giống như cách bạn có thể ghi vào bảng điều khiển.

#include <fstream> 

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

Bây giờ có một điểm chúng tôi có thể bắt đầu: có cách nào chúng tôi có thể xuất ra bảng điều khiển và tệp cùng một lúc không?

Gần đây tôi đã viết dòng demultiplexer để giải quyết vấn đề đó:

#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); 
    } 
}; 

Bạn có thể sử dụng nó như thế này:

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

cách tiếp cận của tôi có ưu điểm là thao tác và sản lượng chưa định dạng hoạt động chính xác:

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

Cảm ơn bạn rất nhiều vì đã giúp đỡ. Để xấu không có một cách đơn giản hơn mặc dù. – Bob

4

Cách dễ dàng trong một môi trường UNIX-như là sử dụng lệnh shell tee:

$ my-program | tee output.txt 

sẽ copy stdout đến nhà ga, và cũng vào tệp output.txt.


Nếu bạn phải làm điều đó trong mã, bạn có thể sử dụng dòng sản lượng riêng của bạn thay vì cout, mà sẽ chuyển mỗi operator<< hai (hoặc nhiều) ostreams. Điều này cảm thấy đẹp hơn (với tôi) hơn so với mucking xung quanh với các tập tin đầu ra C nằm bên dưới C++ ostream cout.

#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; 
} 

Sau đó, nếu bạn thay thế dòng freopen của bạn với:

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

bạn chỉ có thể sử dụng tee << thay vì cout <<.

Lưu ý rằng bạn cần phải vượt qua tee vào các chức năng của mình hoặc làm cho nó hoạt động toàn cầu để hoạt động.

+0

Cũng lưu ý rằng bạn không thể 'tee << endl;' do đó bạn sẽ phải sử dụng ''\ n'' và thực hiện' Tee.flush() 'nếu bạn muốn chức năng đó. – feetwet

Các vấn đề liên quan