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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1877500/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:27:58  来源:igfitidea点击:

C++ stl stringstream direct buffer access

c++stl

提问by Kugel

this should be pretty common yet I find it fascinating that I couldn't find any straight forward solution.

这应该很常见,但我发现我找不到任何直接的解决方案很有趣。

Basically I read in a file over the network into a stringstream. This is the declaration:

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

std::stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);

Now I have some C library that wants direct access to the read chunk of the memory. How do I get that? Read only access is OK. After the C function is done, I dispose of the memorystream, no need for it.

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

str()copies the buffer, which seems unnecessary and doubles the memory.

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

Am I missing something obvious? Maybe a different stl class would work better.

我错过了一些明显的东西吗?也许不同的 stl 类会更好。

Edit: Apparently, stringstream is not guaranteed to be stored continuously. What is?

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

if I use vector<char>how do I get byte buffer?

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

采纳答案by CB Bailey

You can call str()to get back a std::string. From there you can call c_str()on the std::stringto get a char*. Note that c_str()isn't officially supported for this use, but everyone uses it this way :)

你可以打电话str()取回一个std::string. 从那里,你可以叫c_str()std::string获得char*。请注意,c_str()此用途并未得到官方支持,但每个人都以这种方式使用它:)

Edit

编辑

This is probably a better solution: std::istream::read. From the example on that page:

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

  buffer = new char [length];

  // read data as a block:
  is.read (buffer,length);

回答by Pieter

You can take full control of the buffer used by writing the buffer yourself and using that buffer in the stringstream

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

stringstream membuf(std::ios::in | std::ios::out | std::ios::binary);
membuf.rdbuf(yourVeryOwnStreamBuf);

Your own buffer should be derived from basic_streambuf, and override the sync()and overflow()methods appropriately.

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

For your internal representation you could probably use something like vector< char >, and reserve()it to the needed size so that no reallocations and copies are done.

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

This implies you know an upper bound for the space needed in advance. But if you don't know the size in advance, and need a continguous buffer in the end, copies are of course unavoidable.

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

回答by CB Bailey

std::stringstreamdoesn't (necessarily) store its buffer contiguously but can allocate chunks as it is gradually filled. If you then want all of its data in a contiguous region of memory then you will need to copy it and that is what str()does for you.

std::stringstream不(必须)连续存储其缓冲区,但可以在逐渐填充时分配块。如果您随后希望将其所有数据都放在一个连续的内存区域中,那么您将需要复制它,这str()对您有用。

Of course, if you want to use or write a class with a different storage strategy then you can, but you don't then need to use std::stringstreamat all.

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

回答by Don Wakefield

Well, if you are seriously concerned about storage, you can get closer to the metal. basic_stringstreamhas a method, rdbuf()which returns it's basic_stringbuf(which is derived from basic_streambuf). You can then use the eback(), egptr(), and gptr()pointers to access characters directly out of the buffer. I've used this machinery in the past to implement a custom buffer with my desired semantics, so it is do-able.

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

Beware, this is not for the faint of heart! Set aside a few days, read Standard C++ IOStreams and Locales, or similar nitpicky reference, and be careful...

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