C++ stl stringstream direct buffer access

匿名 (未验证) 提交于 2019-12-03 02:06:01

问题:

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 how do I get byte buffer?

回答1:

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 offically 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);


回答2:

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.



回答3:

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.



回答4:

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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!