标签: streambuf

从streambuf派生而不重写相应的流

几天前,我决定编写一个streambuf使用mmap和预读的子类会很有趣.我看了一下我的STL(SGI)如何实现filebuf和实现basic_filebuf包含a FILE*.所以继承basic_filebuf是不可能的.

所以我继承了basic_streambuf.然后我想把我绑mmapbuf到一个fstream.

我认为我唯一需要做的就是复制filebuf...... 的隐式接口,但这是一个明显的错误.在SGI,basic_fstream拥有一个basic_filebuf.无论我是否打电话basic_filestream.std::::ios::rdbuf( streambuf* ),文件流都完全忽略它并使用它自己的filebuf.

所以现在我有点困惑......当然,我可以创建我自己的mmfstream,这将是确切的复制/粘贴,fstream但听起来真的不是面向DRY的.

我无法理解的是:为什么fstream这么紧密地耦合在一起filebuf,所以除了一个以外什么都不可能使用filebuf分离流和bufs的关键在于可以使用具有不同缓冲区的流.

解决方案:

=> filestream应该依赖于隐式接口filebuf.也就是说,fstream应该由streambuf类进行模板化.这将允许每个人提供自己的streambuf子类,fstream只要它实现了filebuf隐式接口.问题:我们无法添加模板参数,fstream因为它会在fstream用作模板模板参数时破坏模板选择器.

=> filebuf应该是一个没有任何附加属性的纯虚拟类.这样一个人就可以从中继承而不携带所有的FILE*垃圾.

你对这个问题的想法?

c++ fstream mmap stream streambuf

4
推荐指数
1
解决办法
2722
查看次数

为什么"gptr"类型为basic_streambuf char_type*而不是const char_type*?

basic_streambuf设置streambuf的三个"gptrs" 的成员setg被声明为:

protected:
  void setg(char_type *gback, char_type *gptr, char_type *egptr);
Run Code Online (Sandbox Code Playgroud)

我想知道:为什么每个gptr的类型char_type*而不是const char_type*const_cast在这里使用const char指针这些gptrs 是否安全?

c++ iostream const-correctness streambuf

4
推荐指数
1
解决办法
461
查看次数

streambuf得到streampos

我将C++ streambuf类用于编译器项目,并且需要一种方便的方法来获取流中的当前位置.

有两个成员函数,streambuf::pubseekpos和一个streambuf::pubseekoff,来修改位置,我很困惑没有streambuf::pubgetpos成员函数(或类似的东西)来阅读它.

似乎有两种可能的解决方法:

  1. 我可以将当​​前位置保存在单独的变量中,并在每次从流中读取字符时手动修改它.

  2. 我可以调用streambuf::pubseekoff(0, ios_base::cur),返回新的流位置.

对于这样一个微不足道的任务,第二种选择似乎是可用的,但是效率低下且不美观.有没有更好的方法呢?

c++ stl stream streambuf

4
推荐指数
1
解决办法
782
查看次数

自定义输入流。流缓冲和下溢方法

为了理解输入流的工作原理,我设计了以下两个类:

#include <iostream>

class my_streambuf: public std::streambuf
{
private:
  std::streambuf* buffer;

  char ch;

protected:

  virtual std::streambuf::int_type underflow()
  {
    std::streambuf::int_type result = buffer->sbumpc();

    if (result != traits_type::eof())
    {
      ch = traits_type::to_char_type(result);

      setg(&ch, &ch, &ch + 1);
    }

    return result;
  }

public:
  my_streambuf(std::streambuf* buffer) : buffer(buffer) {};

  virtual ~my_streambuf() {};
};

class my_istream: public std::istream
{
public:
  my_istream(std::istream& stream) : std::istream(new my_streambuf(stream.rdbuf())) {};

  virtual ~my_istream()
  {
    delete rdbuf();
  }
};

int main()
{
  char s[32];
  my_istream is(std::cin);

  is >> s;
  std::cout << …
Run Code Online (Sandbox Code Playgroud)

c++ io stream streambuf

4
推荐指数
1
解决办法
2586
查看次数

std::stringstream::flush() 应该做什么?

std::ostream有一个flush()方法:

将未提交的更改写入基础输出序列。

这对 a 意味着什么std::stringstream?如果我理解正确,这意味着对于这样的流没有什么可做的。这是真的?

c++ stringstream streambuf c++-standard-library

3
推荐指数
1
解决办法
161
查看次数

我的overflow()实现有什么问题?

我正在尝试实现一个流缓冲区,我在制作overflow()工作时遇到了麻烦.我将缓冲区调整了10个以上的字符并使用重置缓冲区setp.然后我将指针递回到我们离开的地方.由于某种原因,输出不正确:

template <class charT, class traits = std::char_traits<charT>>
class stringbuf : public std::basic_stringbuf<charT, traits>
{
public:
    using char_type   = charT;
    using traits_type = traits;
    using int_type    = typename traits::int_type;
public:
    stringbuf()
        : buffer(10, 0)
    {
        this->setp(&buffer.front(), &buffer.back());
    }

    int_type overflow(int_type c = traits::eof())
    {
        if (traits::eq_int_type(c, traits::eof()))
            return traits::not_eof(c);

        std::ptrdiff_t diff = this->pptr() - this->pbase();

        buffer.resize(buffer.size() + 10);
        this->setp(&buffer.front(), &buffer.back());

        this->pbump(diff);

        return traits::not_eof(traits::to_int_type(*this->pptr()));
    }
    // ...
    std::basic_string<charT> str()
    {
        return buffer;
    }
private:
    std::basic_string<charT> buffer;
}; …
Run Code Online (Sandbox Code Playgroud)

c++ streambuf c++11

2
推荐指数
1
解决办法
484
查看次数

boost :: asio :: async_read和boost :: asio :: streambuf

我正在使用streambuf的async_read.但是,我想将读取的数据量限制为4,因此我可以在转到正文之前正确处理标题.

我怎么能用async_read做到这一点?

c++ boost streambuf boost-asio

1
推荐指数
1
解决办法
2086
查看次数

扩展 std::cout

std::cout我想扩展使用我自己的控制台/cout 包装类的用法。

理想情况下,我会有 2 个 ostream,一个用于常规打印,另一个用于附加新行。

std::ostream Write;
Write << "Hello, I am " << 99 << " years old.";
Run Code Online (Sandbox Code Playgroud)

印刷Hello, I am 99 years old.

std::ostream WriteLine;
WriteLine << "Hello, I am " << 99 << " years old.";
Run Code Online (Sandbox Code Playgroud)

打印Hello, I am 99 years old.\n(一个实际的新行,而不仅仅是转义)

然后,我想扩展它以具有错误流(例如Error和),该错误流在消息之前添加前缀并以不同的颜色打印。ErrorLine"ERROR: "

我知道我必须创建自己的流来添加此功能,并且我遵循C++ cout 并使用前缀作为前缀std::cout,这几乎是我想要的,但不完全是。我不知道如何在流的末尾添加新行,并且前缀不可靠,特别是当我要执行多个打印语句时。

我还应该提到我不想使用重载运算符来实现这种效果,因为我希望能够以菊花链方式连接事物。

什么不起作用

如果我WriteLine >> "First";这样做,WriteLine << "Second";我会得到奇怪的结果,例如SecondFirst\nSecond\nFirst。我理想的输出是First\nSecond\n. …

c++ winapi cout ostream streambuf

0
推荐指数
1
解决办法
1693
查看次数

如何防止`std::cin`或`\n`刷新`std::cout`的缓冲区?

让我们想象一下我的程序需要用户在不同时间输入。我希望这个输入可以防止刷新cout缓冲区。我可以在不同的流缓冲区上设置cin和吗?cout

相关示例:一个程序读取一行中的两个数字 , n1 n2,并且取决于第一个数字是0, 1, 或2

  • n1 = 0:将第二个数字写入n2向量v
  • n1 = 1:输出v[n2]cout
  • n1 = 2pop_back()v

MWE 为:

#include <iostream>
#include <vector>

using namespace std;

int main() {
    int size, n1, n2;
    vector<int> v;
    cin >> size;

    while(size--){
        cin >> n1;

        if (n1 == 0)
        {
            cin >> n2;
            v.push_back(n2);
        }
        else if (n1 == 1)
        { …
Run Code Online (Sandbox Code Playgroud)

c++ io iostream streambuf

0
推荐指数
1
解决办法
551
查看次数