2014-03-01 49 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