Redirecting std::cout - c++

I need a class that redirects one ostream to another ostream during the lifetime of its object. After some tinkering I came up with this:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}
It seems to work fine. However, it's weird that the following line is repeated in both the constructor and destructor:
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
I think it's correct, but I would like to verify with the SO community. Can you find any errors or dangers in this code?
Edit
Make non-copyable.

The reason those lines are the same is because what you're doing is swapping the buffers. (That is, you "redirect" by swapping the original buffer with the redirect buffer; restoration is the swap back.)
While this might give you the intended effect with respect to the output stream, it's not correct because the redirect stream now outputs somewhere else. To redirect means to take one stream and make it output somewhere else; note this doesn't effect that 'somewhere else'.
Your class is not a redirect; as is, it should really be named ScopedStreamSwap. For example, try this instead:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
// oops:
filestream << "also to the file, right?...nope" << std::endl;
filestream << "ah, why am i on the screen?!" << std::endl;
}
std::cout << "After redirect." << std::endl;
// in main, return 0 is implicit, if there is no return statement;
// helpful to keep in mind in snippets and short things
}
What you want is this:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mOldBuffer(inOriginal.rdbuf(inRedirect.rdbuf()))
{ }
~ScopedRedirect()
{
mOriginal.rdbuf(mOldBuffer);
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::streambuf * mOldBuffer;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
// yay:
filestream << "also to the file, right?...yes" << std::endl;
filestream << "i am not on the screen" << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}

Related

Does the stream operator exist for class member functions?

I included the logger from boost. I'm pretty pleased how it works. Just for simplicity and the reason I don't want to use makros to often in my code, I wrap it in a class.
I now wonder if I could use the streaming operator << to write on a member function.
code
class LogWrapper{
...
//debug function
//info function
...
}
void main() {
LogWrapper log;
log.debug() << "some debug msg"; // does this exist?
log.info() << "some info msg";
}
output
[some_timestamp][debug] some debug msg
[some_timestamp][info] some info msg
Is this possible in a good practice, or is it entirely bad style?
It can be done easily like this:
#include <iostream>
class A {
public:
std::ostream &debug() const {
std::cerr << "[timestamp]" << "[DEBUG]";
return std::cerr;
}
};
int main()
{
A a;
a.debug() << "Test";
}
But the important question here is: Should we implement it in this way? In my opinion, NO!
Because you are thinking that the User of the class will print the logs like this:
int main()
{
A a;
a.debug() << "Test" << std::endl;
a.debug() << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
[timestamp][DEBUG]Test2
But what if User chooses this way:
int main()
{
A a;
auto &out = a.debug();
out << "Test" << std::endl;
out << "Test2" << std::endl;
}
Output:
[timestamp][DEBUG]Test
Test2
I would highly recommend not to return stream object. You should use member functions for this purpose.
#include <iostream>
class A {
public:
static void debug(const std::string &log) {
std::cerr << "[timestamp]" << "[DEBUG]" << log << std::endl;
}
};
int main()
{
A::debug("Test 1");
A::debug("Test 2");
}
Output:
[timestamp][DEBUG]Test 1
[timestamp][DEBUG]Test 2

operator<< and stringstream overloading in c++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
Problem:
From overloaded operator<<, cout will only print first bit:``"Hello guys, ", while the stream is multiple shifts << "Hello guys, " << "I can't get here!" << str << "\n"`.
My question is, why I only get the first bit of stream?
Code:
#include <iostream>
#include <sstream>
#include <string>
class Debug {
private:
std::stringstream stream;
public:
std::string str() const{
return stream.str();
}
std::stringstream& operator<<(std::string &s) {
stream << s;
std::cout << s;
return stream;
}
std::stringstream& operator<<(const char s[]) {
stream << s;
std::cout << s;
return stream;
}
};
std::ostream &operator<<(std::ostream &output, const Debug &d) {
output << d.str();
return output;
}
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout <<"\n\n"<< debug;
std::cin.get();
return 0;
}
My question is, why I only get the first bit of stream?
as it was mentioned in the comments, any further calls after the 1st one of the Debug::operator<<() overload, will go to the overloaded operator of std::stringstream because you return a reference to that one.
What you probably want is a class that wraps a std::ostream interface like follows:
class Debug {
std::ostream& os_;
public:
Debug(std::ostream& os) : os_(os) {}
template<typename T>
Debug& operator<<(T val) {
// Intercept whatever you want to intercept here ...
os_ << val;
return *this;
}
};
This will ensure that the Debug::operator<<() overload is called repeatedly when the statement
debug << "Hello guys, " << "I can't get here!" << str << "\n";
is going to be executed.
int main() {
Debug debug(std::cout);
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
return 0;
}
Outputs:
Hello guys, I can't get here!Bad input
See the Live Demo.
To collect the stuff at an inner stream, and just output the contents at a certain point, you can do it as follows:
#include <iostream>
#include <string>
#include <sstream>
class Debug {
std::ostringstream os_;
public:
template<typename T>
Debug& operator<<(T val) {
os_ << val;
return *this;
}
// Overload the operator<< to output the buffered stuff
friend std::ostream& operator<<(std::ostream& os, const Debug& debug) {
os << debug.os_.str();
return os;
}
};
int main() {
Debug debug;
std::string str("Bad input");
debug << "Hello guys, " << "I can't get here!" << str << "\n";
std::cout << debug;
return 0;
}
Another Live Demo.

Concurrent cout formatting

This is an academic question.
sdt::mutex m;
typedef std::lock_guard<std::mutex> G;
void thread1(){
G g(m);
std::cout << std::setw(9);
std::cout << 3.14;
std::cout << std::endl;
}
void thread2(){
G g(m);
std::cout << std::setw(7);
std::cout << 3.14;
std::cout << std::endl;
}
My problem is that the formatting is bound to the output stream, so I need to set all the formatting options ever invented on my thread if I want to be sure about the output I produce. Which will or will not work next year.
Is there any way to reset formatting to default without setting everything by hand?
If not, what are the good workarounds?
For example should I create and keep an std::ostringstream locally on my thread and write oss.str() to std::cout?
I've used boost for brevity but you could write your own optional and state saver.
#include <mutex>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <utility>
#include <boost/io/ios_state.hpp>
#include <boost/optional.hpp>
std::mutex m;
struct save_and_lock
{
boost::optional<boost::io::ios_all_saver> saver;
std::unique_lock<std::mutex> lock;
void init(std::ostream& os)
{
lock = std::unique_lock<std::mutex>(m);
saver.emplace(os);
os.flags(std::ios_base::fmtflags(0));
}
friend std::ostream& operator<<(std::ostream& os, save_and_lock&& s)
{
s.init(os);
return os;
}
};
void thread1(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
void thread2(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
This will work because the evaluation order of user-defined operator << is left to right.

How to trigger action on end-of-statement?

Suppose that I want to create a stream that would perform an action at the end of the statement, so that
myStream << "Hello, " << "World!";
would print "Hello, World!\n" in one shot. Not "Hello, \nWorld!\n" and not "Hello, World!", but "Hello, World\n", as if ; would trigger appending \n and flushing the buffers.
The rationale for that is a stream class that writes to both stdout and a logfile, with the logfile entries having certain prefixes and suffixes.
For example, if my target was HTML I would want this code:
myStream << "Hello, " << "World!";
myStream << "Good bye, " << "cruel World!";
to print like this:
<p>Hello, World!</p>
<p>Good bye, cruel World!</p>
and not like this:
<p>Hello, </p><p>World!</p>
<p>Good bye, </p><p>cruel World!</p>
Now, if I implement LogStream sort of like this:
LogStream & LogStream::operator<<( const std::string & text );
I won't be able to distinguish between << in the middle of the statements from the ones in the beginning/ending of the statements.
If I implement LogStream sort of like this:
LogStream LogStream::operator<<( const std::string & text );
and try to massage the input in the destructor I would get multiple destructors at once at the end of the block.
Finally, I can implement this my requiring endl at the end of each statement, but I'd rather not bother the caller with the necessity to do so.
Thus the question: how one implements such a stream in a caller-transparent fashion?
I implemented something like this once for a custom logging system. I created a class that buffered input and then its destructor flushed the buffer to my log file.
For example:
#include <iostream>
#include <sstream>
#include <string>
class LogStream
{
private:
std::stringstream m_ss;
void flush()
{
const std::string &s = m_ss.str();
if (s.length() > 0)
{
std::cout << s << std::endl;
logfile << "<p>" << s << "</p>" << std::endl;
}
}
public:
LogStream() {}
~LogStream()
{
flush();
}
template <typename T>
LogStream& operator<<(const T &t)
{
m_ss << t;
return *this;
}
template <typename T>
LogStream& operator<<( std::ostream& (*fp)(std::ostream&) )
{
// TODO: if fp is std::endl, write to log and reset m_ss
fp(m_ss);
return *this;
}
void WriteToLogAndReset()
{
flush();
m_ss.str(std::string());
m_ss.clear();
}
};
For single statements that flush on the final ;, each message would use a new instance of the class:
LogStream() << "Hello, " << "World!";
LogStream() << "Good bye, " << "cruel World!";
To allow multiple statements to write to a single message, create the object and do not let it go out of scope until the last statement is done:
{
LogStream myStream;
myStream << "Hello, ";
myStream << "World!";
}
{
LogStream myStream;
myStream << "Good bye, ";
myStream << "cruel World!";
}
To reuse an existing instance for multiple messages, tell it to flush and reset in between each message:
{
LogStream myStream;
myStream << "Hello, " << "World!";
myStream.WriteToLogAndReset();
myStream << "Good bye, " << "cruel World!";
}
I like this approach because it gives the caller more flexibility in deciding when each message is ready to be written to the log file. For instance, I use this to send multiple values to a single log message where those values are obtained from decision-making code branches. This way, I can stream some values, make some decisions, stream some more values, etc and then send the completed message to the log.
The line:
myStream << "Hello, " << "World!";
Is actually multiple statements. It's equivalent to:
ostream& result = myStream << "Hello, ";
result << "World!";
There are some tricks to do what you want by returning an unnamed temporary object (which are destroyed at the end of the full-expression). Here is some example code.
I have a little code that I haven't gotten round to doing anything constructive with that I think is doing what you're asking.
It works by using a proxy class (log_buffer) to build up the string in a std::stringstream object. At the end of the expression the log_buffer proxy object calls the main log_writer
object to process the whole line contained in the std::stringstream.
class log_writer
{
// ultimate destination
std::ostream* sink = nullptr;
// proxy class to do the << << << chaining
struct log_buffer
{
log_writer* lw;
std::stringstream ss;
void swap(log_buffer& lb)
{
if(&lb !=this)
{
std::swap(lw, lb.lw);
std::swap(ss, lb.ss);
}
}
log_buffer(log_writer& lw): lw(&lw) {}
log_buffer(log_buffer&& lb): lw(lb.lw), ss(std::move(lb.ss)) { lb.lw = nullptr; }
log_buffer(log_buffer const&) = delete;
log_buffer& operator=(log_buffer&& lb)
{
swap(lb);
return *this;
}
log_buffer& operator=(log_buffer const&) = delete;
// update the log_writer after the last call to << << <<
~log_buffer() { if(lw) lw->add_line(ss); }
template<typename DataType>
log_buffer operator<<(DataType const& t)
{
ss << t;
return std::move(*this);
}
};
void swap(log_writer& lw)
{
if(&lw != this)
{
std::swap(sink, lw.sink);
}
}
public:
log_writer(std::ostream& sink): sink(&sink) {}
log_writer(log_writer&& lw): sink(lw.sink) { lw.sink = nullptr; }
log_writer(log_writer const&) = delete;
log_writer& operator=(log_writer&& lw)
{
swap(lw);
return *this;
}
log_writer& operator=(log_writer const&) = delete;
// output the final line
void add_line(std::stringstream& ss)
{
// Do any special line formatting here
if(sink) (*sink) << ss.str() << std::endl;
}
template<typename DataType>
struct log_buffer operator<<(DataType const& data)
{
return std::move(log_buffer(*this) << data);
}
};
int main()
{
std::ofstream ofs("test.log");
log_writer lw1(ofs);
log_writer lw2(std::cout);
lw1 << "lw1 " << 2.93 << " A";
lw2 << "lw2 " << 3.14 << " B";
std::swap(lw1, lw2);
lw1 << "lw1 " << 2.93 << " C";
lw2 << "lw2 " << 3.14 << " D";
}

Best way to add a "prompt" message to std::cout

I'm searching the best way to add a custom, initial message to all the messages that std::cout (or std::cerr) prints to console/file output.
For example, if I setup that this custom prompt message will be the string "[Log]", then a classic
std::cerr << "This is a log message" << std::endl;
will be printed in this way:
> [Log] This is a log message
Clearly I can obtain this behavior using
std::string PROMPT_MSG = "[Log]";
std::cerr << PROMPT_MSG << "This is a log message" << std::endl;
but I'd like a less invasive way.
Thanks in advance
You could write your own class:
#include <iostream>
#include <string>
class MyLogger
{
std::ostream & out;
std::string const msg;
public:
MyLogger(std::ostream & o, std::string s)
: out(o)
, msg(std::move(s))
{ }
template <typename T>
std::ostream & operator<<(T const & x)
{
return out << msg << x;
}
};
MyLogger MyErr(std::cerr, "[LOG] ");
Usage:
MyErr << "Hello" << std::endl;
As Joachim Pileborg suggested you can use a logging framework. YOu can use an existing one or start with your own that will contain just one class:
class MyLogger{}
template <typename T>
MyLogger& operator << (MyLogger& logger, const T& logStuff)
{
std::cerr << PROMPT_MSG << logStuff << std::endl;
return logger;
}
then define a global variable of class MyLogger:
MyLogger mylogger;
then when you want to write a log record, write:
mylogger << "This is a log message";
overloaded operator << of class MyLogger will do what you want;
I had the same problem in a recent project. I solved it with this little class:
class DebugOut
{
public:
static const int COLUMN_WIDTH = 15;
DebugOut(const std::wstring &type)
{
std::wcout << type;
for(int i=type.length();i<COLUMN_WIDTH;i++)
std::wcout << " ";
std::wcout << ": ";
}
~DebugOut()
{
std::wcout << std::endl;
}
template <typename T>
friend DebugOut& operator<<(DebugOut& out,T i)
{
std::wcout << i;
return out;
}
};
Sample usage: DebugOut(L"Log") << "Something";
I guess you could just define a function log and a function error, and then just call them when you want to print a log or error method. That way you don't have to add the PROMPT_MSG every time.