Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
545 views
in Technique[技术] by (71.8m points)

c++ - Using freopen() to print to file and screen

I am trying to use freopen() to print to a text file and the screen, but I am only achieving the printing to a file.

I was wondering if there was an easy to save the programs output to a file and print it to the screen? Because I had this working another way, but I ended up having to print out every statement twice. One being for the file the other just for the output.

Note: I am new to C++ and I am trying to learn it for a class next semester so direct answer are needed as I have already look online and couldn't find any simple answers to this solution besides.

Here is what I have so far:

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

using namespace std; 

void menu(){
    cout << "********************************************************
"
         << "* Welcome to slot machine.                             *
"
         << "* Would you like to play? (1 to play, 2 not to play)   *
"
         << "********************************************************

";
    return;
}

void update(int arr[], int &token) {
    if (arr[0]==arr[1] && arr[1]==arr[2]) {
        token+=4;
        cout << "You win

";
    } else if (arr[0]==arr[1] || arr[1]==arr[2] || arr[0]==arr[2]) {
        token+=1;
        cout << "You got two out of three

";
    } else {
        token-=1;
        cout << "You lose

";
    }
}

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

"
             << "Pull? (1 to pull, 2 not to pull)

";
        cin>>x;
        if(x==1) {
            for(int i=0; i<3; i++) {
                arr[i]=1+rand()%10;
            }
            cout << "";
            for(int j=0; j<3; j++) {
                cout << arr[j] << " ";
            }
            cout << "

";
            update(arr,token);
        }
        else{  
            cout << "OK
";
        }
    }
    cin.get();
    return 0;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I don't know a simple way to achieve that, but I've managed to solve this somehow.

Using fstreams you can output to file the same way you can write to console.

#include <fstream>

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

Now there's a point we can start: is there a way we can output to the console and file simultaneously?

I've recently written stream demultiplexer to address that problem:

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

You can use it like this:

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

My approach has advantage that manipulators and unformatted output works correctly:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...