使用std :: ostream在每行之前插入文本

Joh*_*ann 1 c++ iostream stl

我想知道是否可以从std :: ostream继承,并以某种方式覆盖flush(),以便将某些信息(例如行号)添加到每行的开头.然后我想通过rdbuf()将它附加到std :: ofstream(或cout),这样我得到这样的东西:

ofstream fout("file.txt");
myostream os;
os.rdbuf(fout.rdbuf());

os << "this is the first line.\n";
os << "this is the second line.\n";
Run Code Online (Sandbox Code Playgroud)

会把它放到file.txt中

1 this is the first line.
2 this is the second line.
Run Code Online (Sandbox Code Playgroud)

0x4*_*2D2 5

flush()虽然你走在正确的轨道上,但在这种情况下不会覆盖的功能.您应该overflow()在底层std::streambuf接口上重新定义.例如:

class linebuf : public std::streambuf
{
public:
    linebuf() : m_sbuf() { m_sbuf.open("file.txt", std::ios_base::out); }

    int_type overflow(int_type c) override
    {
        char_type ch = traits_type::to_char_type(c);
        if (c != traits_type::eof() && new_line)
        {
            std::ostream os(&m_sbuf);
            os << line_number++ << " ";
        }

        new_line = (ch == '\n');
        return m_sbuf.sputc(ch);
    }

    int sync() override { return m_sbuf.pubsync() ? 0 : -1; }
private:
    std::filebuf m_sbuf;
    bool new_line = true;
    int line_number = 1;
};
Run Code Online (Sandbox Code Playgroud)

现在你可以这样做:

linebuf buf;
std::ostream os(&buf);

os << "this is the first line.\n";  // "1 this is the first line."
os << "this is the second line.\n"; // "2 this is the second line."
Run Code Online (Sandbox Code Playgroud)

Live example