2014-03-01 33 views
1

我有一個非常簡單的流緩衝區設置,將流中的字節轉發到緩衝區。當我打印時,我得到一個奇怪的輸出,即"HellHelllo,"而不是"Hello"。也許我的眼睛很累,但我在這裏找不到問題。爲什麼我得到的是輸出?爲什麼這個流緩衝區不工作?

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

class io_buffer : public std::streambuf 
{ 
public: 
    io_buffer(std::istream& is, int buf_size = 4) 
     : size(buf_size) , is_(is) , buffer(std::max(buf_size, 1)) 
    { 
     char* end = &buffer.front() + buffer.size(); 
     setg(end, end, end); 
    } 

    int_type underflow() 
    { 
     if (gptr() < egptr()) 
      return traits_type::to_int_type(*gptr()); 

     if (is_) 
     { 
      std::copy_n(std::istreambuf_iterator<char>(is_), 
         size, std::back_inserter(buffer)); 

      char* beg = &buffer.front(); 
      setg(beg, beg, beg + buffer.size()); 
      return traits_type::to_int_type(*gptr()); 
     } 
     return traits_type::eof(); 
    } 
private: 
    int size; 
    std::istream& is_; 
    std::vector<char> buffer; 
}; 

int main() 
{ 
    std::istringstream oss("Hello, World"); 
    io_buffer buf(oss); 

    std::istream is(&buf); 
    std::string str; 

    is >> str; 
    std::cout << str << std::endl; // "HellHelllo," 
} 

回答

2

你有(也許4)歸零

buffer(std::max(buf_size, 1)) 

初始化緩衝區和追加內容到緩衝區不清除緩存。

你可以將它更改爲:

int_type underflow() 
{ 
    if (gptr() < egptr()) 
     return traits_type::to_int_type(*gptr()); 

    if (is_) 
    { 
     char* beg = buffer.data(); 
     char* end = std::copy_n(
      std::istreambuf_iterator<char>(is_), 
      size, beg); 
     setg(beg, beg, end); 
     return traits_type::to_int_type(*gptr()); 
    } 
    return traits_type::eof(); 
} 

你還有一個錯誤的位置:性病:: copy_n可能會問太多的字符。

讓它:

int_type underflow() 
{ 
    if (gptr() < egptr()) 
     return traits_type::to_int_type(*gptr()); 

    if (is_) 
    { 
     char* beg = buffer.data(); 
     char* end = beg; 
     char* limit = beg + buffer.size(); 
     std::istreambuf_iterator<char> in(is_); 
     std::istreambuf_iterator<char> eos; 
     for(; end < limit && in != eos; ++end, ++in) 
      *end = *in; 
     setg(beg, beg, end); 
     if(beg < end) 
      return traits_type::to_int_type(*gptr()); 
    } 
    return traits_type::eof(); 
} 

,消除成員的大小。

1

我認爲這是因爲underflow被調用兩次。

這可能是a bug

+0

緩衝區大小是一個默認參數。而且我很小心確保它變得很小,以便他可以測試'underflow()'。 – 0x499602D2

+0

是的,但設置爲「4」,需要更大的數字。 –

+0

他有意將它設置爲4,以便他可以測試'underflow()'。 – 0x499602D2