使用iostream或替代方案来管理流

时间:2015-12-10 14:15:18

标签: c++ iostream

我想编写一个函数,其中(简化)将可变大小的输入缓冲区作为参数,对其进行处理(顺序),并返回固定大小的缓冲区。缓冲区的剩余部分必须留在"管道中#34;用于下一次调用函数。

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

问题2: 如何全局声明iostream对象?实际上,由于我有几个流,我需要在struct-vector中编写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);
}

2 个答案:

答案 0 :(得分:0)

我认为这里不需要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
}

答案 1 :(得分:0)

  

问题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对象?实际上,由于我有几个流,我需要在struct-vector中编写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
    }
}