简体   繁体   中英

ofstream - Can I redirect a “cout” into file?

I just wanted to know if there was some way yo be able to do this :

ofstream exemple (name);
exemple << Display();

Display() being a void method, that only do something like that :

cout << "Something" << endl;

I would do that because I have already written all the methods Display() for each class and I would like to put what they send to cout into my file, instead or recreate some methods "string Display()".

Is it possible?

Thank's! Marco

You can change cout 's buffer , but cout is a global variable so that will affect the whole program.

Why don't you make Display() receive the output stream as parameter?

void Display(std::ostream &cout) {
    cout << "Something" << endl;
}

No, not like that. You cannot use the result of a void function, ever, because it does not have one.

It is possible to hack around with the underlying buffer of std::cout , swapping it for example 's, but I would not recommend this ... and the code in your question would still be invalid.

You could do this:

#include <ostream>
#include <fstream>

void Display(std::ostream& os)
{
    os << "Something" << std::endl;
}

int main()
{
   const std::string name = "someFile.txt";
   std::ofstream example(name);
   Display(example);
}

You can make Display a helper function of a manipulator display_msg , a class which encapsulates the output. Display cannot return void , because if you are looking for the syntax os << Display() to work, Display will have to return something other than void .

Here is the definition of display_msg :

 class display_msg { }; 

The class is left empty because it performs nothing of importance. We will overload the insertion operator for this class so that we can access the output stream and insert our custom data into:

 std::ostream& operator<<(std::ostream& os, const display_msg&) { return os << "My message"; } 

This is a very simple setup. But as you said, you would like for the output to be redirected to standard output ( std::cout ). For that you will have to copy the buffer of std::cout to the file stream. You can do that using RAII (in order to manage lifetime dependencies between the objects):

 struct copy_buf { public: copy_buf(std::ios& lhs, std::ios& rhs) : str(lhs), buf(lhs.rdbuf()) { lhs.rdbuf(rhs.rdbuf()); } ~copy_buf() { str.rdbuf(buf); } private: std::ios& str; std::streambuf* buf; }; 

The inserter can use this like so:

 std::ostream& operator<<(std::ostream& os, const display_msg&) { copy_buf copy(os, std::cout); return os << "My message"; } 

Display is a simple helper function that returns the class:

 display_msg Display() { return display_msg(); } std::ifstream f("in.txt"); f << Display(); // redirects to standard output 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM