C++ stl stringstream直接缓冲区访问

Kug*_*gel 30 c++ stl

这应该是相当普遍的但我发现我找不到任何直接的解决方案令人着迷.

基本上我通过网络将文件读入字符串流.这是声明:

std::stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);
Run Code Online (Sandbox Code Playgroud)

现在我有一些C库需要直接访问内存的读取块.我怎么做到的?只读访问权限就可以了.C函数完成后,我处理了内存流,不需要它.

str() 复制缓冲区,这似乎是不必要的,并使内存翻倍.

我错过了一些明显的东西吗 也许一个不同的stl类可以更好地工作.

编辑:显然,不保证stringstream连续存储.什么是?

如果我使用vector<char>如何获得字节缓冲区?

Pie*_*ter 15

您可以通过自己编写缓冲区并使用缓冲区来完全控制所使用的缓冲区 stringstream

stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);
membuf.rdbuf(yourVeryOwnStreamBuf);
Run Code Online (Sandbox Code Playgroud)

您应该从自己的缓冲区派生basic_streambuf,并适当地覆盖sync()overflow()方法.

对于您的内部表示,您可以使用类似的东西vector< char >,并将reserve()其用于所需的大小,以便不进行重新分配和复制.

这意味着您事先知道所需空间的上限.但如果你事先不知道尺寸,最后需要一个连续的缓冲区,副本当然是不可避免的.


CB *_*ley 12

std::stringstream不必(必然)连续存储其缓冲区,但可以在逐渐填充时分配块.如果您希望将所有数据放在连续的内存区域中,那么您将需要复制它,这就是str()为您做的.

当然,如果您想使用或编写具有不同存储策略的类,那么您可以,但是您根本不需要使用它std::stringstream.


小智 9

您可以调用str()以获取std :: string.从那里你可以调用std::stringstd :: string来得到一个c_str().请注意,c_str()在此用途中不受官方支持,但每个人都以这种方式使用它:)

编辑

这可能是一个更好的解决方案:std::string.从该页面上的示例:

  buffer = new char [length];

  // read data as a block:
  is.read (buffer,length);
Run Code Online (Sandbox Code Playgroud)

  • 男人,那就是缓冲区的三倍. (7认同)
  • `c_str()`是`std :: basic_string`标准接口的一部分.除了它返回一个`const char*`的小细节(以及无论如何要求只读访问的问题),如何不支持`c_str`的​​使用? (2认同)
  • 当你说"每个人都这样使用它"时,我认为你使用了错误的词 - 你的意思是"没有人". (2认同)

Don*_*eld 6

好吧,如果你真的担心存储,你可以更接近金属.basic_stringstream有一个方法,rdbuf()返回它的basic_stringbuf(它是从basic_streambuf派生的).然后,您可以使用eback(),egptr()gptr()指针直接从缓冲区中访问字符.我过去曾使用过这个机器来实现一个带有我想要的语义的自定义缓冲区,所以它是可行的.

当心,这不适合胆小的人!留出几天,阅读标准C++ IOStreams和Locales,或类似的挑剔参考,并小心......

  • `eback`、`egptr` 和 `gptr` 受到保护,因此获取 `stringbuf` 的 `rdbuf` 指针不会让您访问这些。即使确实如此,我也不认为可以_保证_您可以使用比 `.str()` 和 `.data()` 更少的副本创建底层序列的连续副本。 (2认同)