为什么这个流缓冲区不工作? [英] Why is this stream buffer not working?

查看:83
本文介绍了为什么这个流缓冲区不工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的流缓冲区设置,将流从字节流转发到缓冲区。当我打印我得到一个奇怪的输出,即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 );

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>缓冲;
};

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

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

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


解决方案

您可以用(可能4)零初始化缓冲区

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


$ b

您可以将其更改为:

  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();
}

这里还有一个错误:std :: copy_n可能要求太多字符。



创建:

  int_type underflow $ b {
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();
}

并消除会员人数。


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". 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

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.

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.

这篇关于为什么这个流缓冲区不工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆