C++ cout with prefix

后端 未结 4 1678
醉话见心
醉话见心 2021-01-07 14:15

I want a ostream with a prefix at the beginning of every line redirected on cout; I try this:

#include 
#include 
class paralle         


        
4条回答
  •  攒了一身酷
    2021-01-07 15:05

    The way you modify the behavior of std::ostream is not by overloading any of the output operators! Instead, you derive a class from std::streambuf and override the virtual functions overflow() and sync(). In you case you'd probably create a filtering stream buffer, i.e., you'd take another std::streambuf as argument and write a somehow modified stream of characters to this stream buffer.

    Here is a quick example:

    #include 
    
    class prefixbuf
        : public std::streambuf
    {
        std::string     prefix;
        std::streambuf* sbuf;
        bool            need_prefix;
    
        int sync() {
            return this->sbuf->pubsync();
        }
        int overflow(int c) {
            if (c != std::char_traits::eof()) {
                if (this->need_prefix
                    && !this->prefix.empty()
                    && this->prefix.size() != this->sbuf->sputn(&this->prefix[0], this->prefix.size())) {
                    return std::char_traits::eof();
                }
                this->need_prefix = c == '\n';
            }
            return this->sbuf->sputc(c);
        }
    public:
        prefixbuf(std::string const& prefix, std::streambuf* sbuf)
            : prefix(prefix)
            , sbuf(sbuf)
            , need_prefix(true) {
        }
    };
    
    class oprefixstream
        : private virtual prefixbuf
        , public std::ostream
    {
    public:
        oprefixstream(std::string const& prefix, std::ostream& out)
            : prefixbuf(prefix, out.rdbuf())
            , std::ios(static_cast(this))
            , std::ostream(static_cast(this)) {
        }
    };
    
    int main()
    {
        oprefixstream out("prefix: ", std::cout);
        out << "hello\n"
            << "world\n";
    }
    

    Stream buffers conceptually keep an internal buffer which is, however, not set up in the example above. Every time there is no space for a character to be written to the output buffer, the virtual function overflow() is called with a character (it may also be called with the special value std::char_traits::eof() which is typically used to flush the buffer). Since there is no buffer, overflow() will be called for every character. All this function does is to see if it needs to write a prefix and, if so, writes the prefix. In case a newline '\n' is written, the function remembers that it needs to write the prefix if another character is written. It then just forwards writing of the character to the underlying stream buffer.

    The virtual function sync() is used to synchronize the stream with its external representation. For a stream buffer keeping a buffer it makes sure that any buffer is written. Since the prefixbuf doesn't really keep a buffer, all it needs to is to delegate the sync() request to the underlying stream buffer by calling pubsync().

提交回复
热议问题