[英]Why is this stream buffer not working?
I have a very simple stream buffer setup that forwards the bytes from a stream to the buffer. 我有一个非常简单的流缓冲设置,它将字节从流转发到缓冲区。 When I print I get a weird output, namely
"HellHelllo,"
instead of "Hello"
. 当我打印时,我得到一个奇怪的输出,即
"HellHelllo,"
而不是"Hello"
。 Maybe my eyes are tired, but I can't find the problem here. 也许我的眼睛很累,但我在这里找不到问题。 Why am I getting is output?
为什么我得到输出?
#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,"
}
You initialize the buffer with (maybe 4) zeros 用(可能是4个)零初始化缓冲区
buffer(std::max(buf_size, 1))
and append the content to the buffer without clearing the buffer. 并将内容附加到缓冲区而不清除缓冲区。
You may change it to: 您可以将其更改为:
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();
}
You still have a bug here: std::copy_n might ask for too many characters. 你这里仍然有一个错误:std :: copy_n可能会要求太多字符。
Make it: 做了:
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();
}
And eliminate the member size. 并消除会员规模。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.