What's wrong with my overflow()
here. When I print oss.str()
it prints "Hello, Wor"
instead of "Hello, World"
. What did I do wrong?
#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;
}
You need to flush also a std::vector
(buffer), i.e:
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);
}
Even better, as 0x499602D2 address suggested use pbump(-buffer.size())
to avoid multiple calls to overflow()
.
Watch out for your destructor as it is required to do a flush: