3

I am looking for a way of adding a prefix to an ostream, pass it down to other functions so that their outputs are prefixed and then remove it to continue.

Check the following pseudocode:

...
void function(ostream &out){
    out << "output 1\n";
    out << "output 2\n";
}

cout << "Whatever\n";
add_suffix(cout,"function: ");
function(cout);
remove_suffix(cout);
...

With an output like:

...
Whatever
function: output 1
function: output 2
...

Looking at the docs of ostream they state that sentry might be used for prefixing/suffixing but i don't know how to do this if the intended use is what I want.

The ostream::sentry documentation says:

sentry: Perform exception safe prefix/suffix operations
ehfeng
  • 3,807
  • 4
  • 33
  • 42
Arkaitz Jimenez
  • 22,500
  • 11
  • 75
  • 105

2 Answers2

4

The general way goes like this: Define YourStreamBuffer that is a streambuf that inserts your prefix after any newline that is written to it, and sends the output to a destination buffer. Then use it like this:

streambuf *oldBuf = cout.rdbuf();

YourStreamBuffer yourBuf(oldBuf, "function: ");
// everything written to yourBuf is sent to oldBuf

cout.rdbuf(&yourBuf);
function(cout);
cout.rdbuf(oldBuf);

You can find plenty examples on the net on how to implement your stream buffers. Also make sure that your code is exception safe, that is restore oldBuf even if an exception is thrown.

Note: sentries are something different, it's not what you need here.

Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
  • I am aware about streambufs and that was my original idea, i was just wondering why the sentry is documented like that if it doesn't do such a thing. – Arkaitz Jimenez Dec 18 '10 at 21:14
  • 2
    @Arkaitz: "prefix" that is mentioned there is a prefix of a function that reads/writes to the stream. They are meant to check the state of the stream and throw exceptions when the stream is in bad-state. – Yakov Galka Dec 18 '10 at 21:17
  • cool, now it makes sense, its just that prefix and suffix operations on a stream context did look too much like what I wanted, I guess I'm tied to the streambuf implementation then. – Arkaitz Jimenez Dec 18 '10 at 21:19
0

Alternatively, you could use an evil macro for this..

#define f_str(str) str << __FUNCTION__ << ' '

(yes, __FUNCTION__ isn't defined everywhere, but hey...) Negtive is that you have to use the macro to wrap, positive is that it only inserts the name once for all chained stream operations (in the stream buffer case, it'll have a prefix for all new lines [unless that's what you want of course!])

Nim
  • 33,299
  • 2
  • 62
  • 101