我想编写一个函数,其中(简化)将可变大小的输入缓冲区作为参数,对其进行处理(顺序),并返回固定大小的缓冲区。缓冲区的剩余部分必须留在"管道中#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);
}
答案 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
}
}