我在
const char*
指针指向的缓冲区中有一些数据。数据只是一个 ASCII 字符串。我知道它的大小。我希望能够以与从流中读取数据相同的方式读取它。我正在寻找一种解决方案,可以让我编写这样的代码:
// for example, data points to a string "42 3.14 blah"
MemoryStreamWrapper in(data, data_size);
int x;
float y;
std::string w;
in >> x >> y >> w;
重要条件:不得以任何方式复制或更改数据(否则我只会使用字符串流。据我所知,如果不复制,就不可能从 const char 指针创建字符串流数据。)
做到这一点的方法是创建一个合适的流缓冲区。例如,这可以这样做:
#include <streambuf>
#include <istream>
struct membuf: std::streambuf {
membuf(char const* base, size_t size) {
char* p(const_cast<char*>(base));
this->setg(p, p, p + size);
}
};
struct imemstream: virtual membuf, std::istream {
imemstream(char const* base, size_t size)
: membuf(base, size)
, std::istream(static_cast<std::streambuf*>(this)) {
}
};
唯一有点尴尬的是流缓冲区中的
const_cast<char*>()
:流缓冲区不会更改数据,但接口仍然需要使用char*
,主要是为了在“正常”状态下更容易更改缓冲区流缓冲区。这样,您就可以使用 imemstream
作为普通输入流:
imemstream in(data, size);
in >> value;
唯一的方法是子类化 std::istream (这也需要子类化 std::streambuf)来创建自己的从常量内存读取的流类。
这并不像听起来那么容易,因为 C++ 标准库流类非常混乱且设计糟糕。我认为这不值得,除非你需要它来扩展很多。