【问题标题】:use iostream or alternative for managing stream使用 iostream 或替代方法来管理流
【发布时间】:2015-12-10 14:15:18
【问题描述】:

我想编写一个函数,它(简化)将可变大小的输入缓冲区作为参数,(按顺序)处理它,并返回一个固定大小的缓冲区。缓冲区的剩余部分必须留在“管道”中,以便下次调用该函数。

问题 1: 根据我的研究,看起来 iostream 是要走的路,但显然没有人使用它。这是最好的方法吗?

问题 2: 如何全局声明 iostream 对象?实际上,由于我有几个流,我需要将 iostream 对象写入结构向量中。我该怎么做?

目前我的代码如下所示:

struct membuf : std::streambuf
{
    membuf(char* begin, char* end) {
    this->setg(begin, begin, end);
    }
};

void read_stream(char* bufferIn, char* BufferOut, int lengthBufferIn)
{
    char* buffer = (char*) malloc(300);         //How do I do this globally??
    membuf sbuf(buffer, buffer + sizeof(buffer));//How do I do this globally??
    std::iostream s(&sbuf);             //How do I do this globally??

    s.write(bufferIn,  lengthBufferIn);
    s.read(BufferOut, 100);
    process(BufferOut);
}

【问题讨论】:

  • 对我来说,你想要达到的目标并不是 100% 清楚,但听起来你应该看看 std::queuestd::deque

标签: c++ iostream


【解决方案1】:

我认为这里不需要iostream。您可以创建一个对象,该对象具有对缓冲区(因此不涉及副本)及其所在位置的引用。

所以有些东西:

class Transformer {
private:
   char const *input_buf_;

public:
   Transformer(char const *buf) : input_buf_(buf) {
   }

   bool has_next() const { return input_buf_ != nullptr; } // or your own condition

   std::array<char, 300> read_next() {
       // read from input_buf_ as much as you need
       // advance input_buf_ to the remaining part
       // make sure to set input_buf_ accordingly after the last part
       // e.g. input_buf_ = nullptr; for how I wrote hasNext
       return /*the processed fixed size buffer*/;
   }
}

用法:

char *str == //...;
Transformer t(str);

while (t.has_next()) {
   std::array<char, 300> arr = t.read_next();
   // use arr
}

【讨论】:

    【解决方案2】:

    问题 1:根据我的研究,看起来 iostream 是可行的方法,但显然没有人使用它。这是最好的方法吗?

    是的(std::istream 类和特化是用来管理流的,它们很适合这个问题)。

    您的代码可能如下所示:

    struct fixed_size_buffer
    {
        static const std::size_t size = 300;
        std::vector<char> value;
        fixed_size_buffer() : value(fixed_size_buffer::size, ' ') {}
    };
    
    std::istream& operator>>(std::istream& in, fixed_size_buffer& data)
    {
        std::noskipws(in); // read spaces as well as characters
        std::copy_n(std::istream_iterator<char>{ in },
             fixed_size_buffer::size);
             std::begin(data.value)); // this leaves in in an invalid state
                                      // if there is not enough data in the input
                                      // stream;
        return in;
    }
    

    消费数据:

    fixed_size_buffer buffer;
    
    std::ifstream fin{ "c:\\temp\\your_data.txt" };
    while(fin >> buffer)
    {
        // do something with buffer here
    }
    
    while(std::cin >> buffer) // read from standard input
    {
        // do something with buffer here
    }
    
    std::istringstream sin{ "long-serialized-string-here" };
    while(sin >> buffer) // read from standard input
    {
        // do something with buffer here
    }
    

    问题 2:如何全局声明 iostream 对象?实际上,由于我有几个流,我需要将 iostream 对象写入结构向量中。我该怎么做?

    iostreams 不支持复制构造;因此,您需要将它们保存在一系列指向基类的指针/引用中:

    auto fin = std::make_unique<std::ifstream>("path_to_input_file");
    std::vector<std::istream*> streams;
    
    streams.push_back(&std::cin);
    streams.push_back(fin.get());
    
    fixed_size_buffer buffer;
    for(auto in_ptr: streams)
    {
        std::istream& in = &in_ptr;
        while(in >> buffer)
        {
            // do something with buffer here
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-19
      • 2019-06-09
      • 2017-04-23
      • 2016-12-07
      • 1970-01-01
      • 1970-01-01
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多