Reputation: 469
In my code I have a a function that takes as argument a boolean variable. If this variable is true then the output shall be redirected to a file. If not, then to std::cout
The code looks like this and Its been inspired by a relevant question [1]
void MyClass::PPrint(bool ToFile)
{
std::streambuf *coutBufferBak = std::cout.rdbuf();
std::ofstream out("out.txt");
if (ToFile) { std::cout.rdbuf(out.rdbuf()); }
std::cout << "Will I be written to a file or to cout ?\n";
if (ToFile) {std::cout.rdbuf(coutBufferBak);} // reset cout
}
But in the case that the ToFile
flag is false
the file will be generated nonetheless and it will be empty. Is there a way to do it so that the file won't be generated ? If for example I try to include on the first IF statement the std::ofstream out("out.txt");
then I will get a SegFault
due to the the variable scope being limited to that if.
Upvotes: 0
Views: 714
Reputation: 62694
Don't redirect std::cout
. Write your print in terms of a std::ostream &
parameter, and choose an appropriate std::ostream
to pass.
void MyClass::PPrintImpl(std::ostream & out)
{
out << "Will I be written to a file or to cout ?\n";
}
// a.k.a
std::ostream & operator <<(std::ostream & out, const MyClass &)
{
return out << "Will I be written to a file or to cout ?\n";
}
void MyClass::PPrint(bool ToFile) {
if (ToFile) {
std::ofstream fout("out.txt");
PPrintImpl(fout);
} else {
PPrintImpl(std::cout);
}
}
We pass std::ostream
s by reference because we the identity, not just the value of the stream object matters. We know this because they aren't copyable (the copy constructor is delete
d)
Upvotes: 3
Reputation: 31579
You can open the file conditionally:
std::ofstream out;
if(...)
out.open("out.txt");
Upvotes: 2