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

发布于 2024-08-14 07:27:52 字数 452 浏览 2 评论 0原文

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

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

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

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

str() 复制缓冲区,这似乎没有必要,并且会使内存增加一倍。

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

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

如果我使用 vector 如何获取字节缓冲区?

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.

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

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

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

一桥轻雨一伞开 2024-08-21 07:27:52

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

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

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

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

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

You can take full control of the buffer used by writing the buffer yourself and using that buffer in the 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.

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.

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.

情场扛把子 2024-08-21 07:27:52

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

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

std::stringstream doesn'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.

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::stringstream at all.

深爱不及久伴 2024-08-21 07:27:52

您可以调用 str() 来获取 std::string。从那里,您可以在 std::string 上调用 c_str() 来获取 char*。请注意,c_str() 并未正式支持此用途,但每个人都以这种方式使用它:)

编辑

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

  buffer = new char [length];

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

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

Edit

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

  buffer = new char [length];

  // read data as a block:
  is.read (buffer,length);
怎言笑 2024-08-21 07:27:52

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

请注意,这不适合胆小的人!留出几天时间,阅读标准 C++ IOStreams 和区域设置,或类似的挑剔参考,并且要小心...

Well, if you are seriously concerned about storage, you can get closer to the metal. basic_stringstream has 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.

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...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文