2

my problem is I have a couple of cout's in various files in the project. I would like all of them to be redirected and saved in .txt file, and what I achieved by now is that only one cout is saved in the file. I don't want to create separate .txt for each cout, for the sake of reading them at once. My code looks now like this:

#include <fstream>
#include <string>
#include <iostream>

int main()
{
    std::ofstream out("out.txt");
    std::cout.rdbuf(out.rdbuf()); 

    std::cout << "get it3";
    std::cout << "get it4"; 
}

Both cout are in one file, but assuming they are in two different, how to redirect and save in one .txt?

11
  • 7
    Why not just re-direct standard output at the command line instead of modifying your program ? Commented Dec 18, 2012 at 8:13
  • 1
    I don't think that it is a good idea. You might want to create some singleton stream, which could be switched everywhere you want, and use it instead of cout Commented Dec 18, 2012 at 8:16
  • I have some couts that I'd like to put in file, but not all. @kassak , I don't know about singleton stream creation, can you throw with some example or good reference please? Commented Dec 18, 2012 at 8:19
  • I think kassak is suggesting that you make one ostream object which could then be set to be either equivalent to an ofstream or cout (or possibly something else). This is not a bad idea, but considering that you want to only selectively output to a file, it won't work. If the data you want to write to a file is of a specific format, it might be possible by writing a class that detects the format (and selects the stream to use) though. Commented Dec 18, 2012 at 8:23
  • What about user-defined literals? (Never to use it for something like this though.) Maybe it's a good idea to define a string type ending on "w" or something. Then you define operator<< for it so that it is written to a file. Commented Dec 18, 2012 at 8:27

1 Answer 1

3

The obvious answer is that you should never output to std::cout. All actual output should be to an std::ostream&, which may be set to std::cout by default, but which you can initialize to other things as well.

Another obvious answer is that redirection should be done before starting the process.

Supposing, however, that you cannot change the code outputting to std::cout, and that you cannot control the invocation of your program (or you only want to change some of the outputs), you can change the output of std::cout itself by attaching a different streambuf. In this case, I'd use RAII as well, to ensure that when you exit, std::cout has the streambuf it expects. But something like the following should work:

class TemporaryFilebuf : public std::filebuf
{
    std::ostream&   myStream;
    std::streambuf* mySavedStreambuf;
public:
    TemporaryFilebuf(
            std::ostream& toBeChanged,
            std::string const& filename )
        : std::filebuf( filename.c_str(), std::ios_base::out )
        , myStream( toBeChanged )
        , mySavedStreambuf( toBeChanged.rdbuf() )
    {
        toBeChanged.rdbuf( this );
    }
    ~TemporaryFilebuf()
    {
        myStream.rdbuf( mySavedStreambuf );
    }
};

(You'll probably want to add some error handling; e.g. if you cannot open the file.)

When you enter the zone where you wish to redirect output, just create an instance with the stream (std::cout, or any other ostream) and the name of the file. When the instance is destructed, the output stream will resume outputting to whereever it was outputting before.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.