字符缓冲区的istream
istream for char buffer
在Qt库中有QByteArray和QDataStream类,它们允许我用非常容易使用的语法将变量读写到内存缓冲区:
QByteArray data = getData();
QDataStream stream( data );
double d = 0;
int i = 0;
stream >> d >> i;
如何用stl流类实现simmilar行为?例如,我有一个constchar*数据和它的大小,所以我想构造std::istream并从该数据中读取变量:
const char* data = getData();
size_t size = getSize();
membuffer buf( data, data + size );
std::istream str( buf );
double d = 0;
str >> d;
请注意,不应复制数据!
假设您有一个固定大小的数据缓冲区及其大小,那么通过创建一个合适的流缓冲区来实现它是微不足道的:
struct membuf: std::streambuf {
membuf(char* begin, char* end) {
this->setg(begin, begin, end);
}
};
这个简单的流缓冲区只是将流缓冲区"获取区域"设置为范围[begin, end)
(begin
的使用次数是设置"放回区域"的两次,在这种情况下,放回区域是空的)。当没有更多的字符可读取时,流将尝试调用默认实现指示失败的underflow()
。如果你想读取更多的字符,你可以覆盖underflow()
,在新设置的缓冲区中提供更多的字符。
有了它,你可以使用这个内存支持的流缓冲区创建一个流:
membuf sbuf(begin, end);
std::istream in(&sbuf);
double d = 0;
if (in >> d) { // always check conversions from string to a value...
// ...
}
为了更方便起见,流缓冲区和流的创建也可以绑定到一个类中。有一个小技巧是,流缓冲区应该更早创建,但这是可行的:
class imemstream: private virtual membuf, public std::istream {
public:
imemstream(char* begin, char* end)
: membuf(begin, end)
, std::ios(static_cast<std::streambuf*>(this))
, std::istream(static_cast<std::streambuf*>(this)) {
}
};
不过,这只是一个警告:创建流比复制大量数据更昂贵。也就是说,如果你想在循环中使用该流,你可能想提供重置缓冲区的功能(可能与清除状态标志相结合)。
相关文章:
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 为什么istream不支持右值提取
- 将无符号char*转换为std::istream*C++
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- Xaudio2在更改缓冲区或循环时弹出声音
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 需要从 istream 和 ostream 派生 iostream
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 多线程双缓冲区
- istream std::cin如何修改自定义istream缓冲区
- 将缓冲区转换为在现有程序中工作的iStream
- IStream COM 读取到缓冲区,然后通过 winsock 发送
- 为C++istream定制流缓冲区
- 字符缓冲区的istream
- 如何在c++中读取标准istream缓冲区
- 从IStream读取到缓冲区(音频)