从常量内存创建输入流

问题描述 投票:0回答:3

我在

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 指针创建字符串流数据。)

c++ input stream
3个回答
72
投票

做到这一点的方法是创建一个合适的流缓冲区。例如,这可以这样做:

#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;

2
投票

唯一的方法是子类化 std::istream (这也需要子类化 std::streambuf)来创建自己的从常量内存读取的流类。

这并不像听起来那么容易,因为 C++ 标准库流类非常混乱且设计糟糕。我认为这不值得,除非你需要它来扩展很多。


0
投票

从 C++23 开始

使用

std::ispanstream
:它是标准库专门为此目的提供的streambuf实现;使用固定缓冲区作为 iostream。对于输入流,这些可以是常量缓冲区。

© www.soinside.com 2019 - 2024. All rights reserved.