这个流缓冲区出了什么问题?

时间:2014-03-01 15:15:47

标签: c++

我的overflow()在这里出了什么问题。当我打印oss.str()时,它会打印"Hello, Wor"而不是"Hello, World"。我做错了什么?

#include <iostream>
#include <vector>
#include <string>
#include <sstream>

class io_buffer : public std::streambuf
{
public:
    io_buffer(std::ostream& os, int buf_size = 4)
        : os_(os), buffer(buf_size)
    {
        os_.clear();
        char* beg = buffer.data();
        setp(beg, beg + buffer.size());
    }

    int_type overflow(int_type c)
    {
        if (os_ && !traits_type::eq_int_type(c, traits_type::eof()))
        {
            *pptr() = traits_type::to_char_type(c);
            pbump(1);

            if (flush())
            {
                setp(buffer.data(), buffer.data() + buffer.size());
                return c;
            } else
                return traits_type::eof();
        }

        return traits_type::not_eof(c);
    }

    bool flush()
    {
        return os_.write(pbase(), pptr() - pbase());
    }

    int sync()
    {
        return flush() ? 0 : -1;
    }
private:
    std::ostream& os_;
    std::vector<char> buffer;
};

int main()
{
    std::ostringstream oss;
    io_buffer buf(oss);

    std::ostream os(&buf);
    std::string str("Hello, World");

    os << str;
    std::cout << oss.str() << std::endl;
}

2 个答案:

答案 0 :(得分:2)

您还需要刷新std::vector(缓冲区),即:

int_type overflow(int_type c)
    {
        if (os_ && !traits_type::eq_int_type(c, traits_type::eof()))
        {
            *pptr() = traits_type::to_char_type(c);
            pbump(1);

            if (flush())
            {
                buffer.clear();  // <-
                setp(buffer.data(), buffer.data() + buffer.size());
                return c;
            } else
                return traits_type::eof();
        }

        return traits_type::not_eof(c);
    }

更好的是,由于0x499602D2地址建议使用pbump(-buffer.size())来避免多次调用overflow()

答案 1 :(得分:0)

问题是您使用:

setp(beg, beg + buffer.size());

并在overflow()中添加没有重新分配的新元素,结束指针应该是可访问的(如果你不想重新分配),否则你需要在overflow()中重新分配你的缓冲区。所以改成它:

setp(beg, beg + buffer.size() - 1);
在io_buffer构造函数中

以及稍后在溢出更改setp中:

pbump(-(pptr() - pbase()));

还要刷新缓冲区添加endl:

os << str << endl;

工作示例: http://coliru.stacked-crooked.com/a/7c72ecfe78bb2aee