2014-03-01 40 views
0

我的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

您还需要刷新一个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()

+0

+1好答案。你有他的正确轨道,但它会更好地执行'pbump(-buffer.size())'而不是清除缓冲区,因为它避免了多次调用overflow()。如果缓冲区没有大小,那么对于每个输出操作,都会调用overflow()。 :) – 0x499602D2

+0

@ 0x499602D2宝贵的提示,谢谢 – 4pie0

0

的问题是,你使用:

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

和溢出()你有没有重新分配添加新的元素,最终指针应该可以访问(如果你不想重新分配),否则你需要在overflow()中重新分配缓冲区。因此,将其更改为:

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

在io_buffer构造

后来在溢出变化值存取到:

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

也刷新你的缓冲区添加ENDL:

os << str << endl; 

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