提问人:Lorah Attkins 提问时间:5/31/2023 最后编辑:Lorah Attkins 更新时间:6/1/2023 访问量:184
strstream 可以直接使用标准字符串的缓冲区吗
Can an strstream directly use the buffer of a standard string
问:
鉴于 strstream 具有以下构造函数:
strstream( char* s, int n, std::ios_base::openmode mode);
我想知道我是否可以直接使用标准字符串底层的缓冲区,当然是在“只读”模式下,以避免缓冲区重新分配的奇怪副作用:
std::string buffer("Dummy Data");
std::strstream ss(
const_cast<char *>(buffer.data()), buffer.length(), std::ios_base::in);
std::string other;
ss >> other;
std::cout << other << std::endl;
令我惊讶的是,上面的代码最终变成了一个空字符串。在文档中有一个示例,其中 C 数组用作 的静态缓冲区,所以我想知道它不能使用缓冲区内容的原因是什么?other
strstream
std::string
注意:我不能使用,因为有问题的平台有一个 VS 实现,其大小限制为 4GB,如此处所述std::stringstream
更新:
我看到使用(如示例中所示)几乎可以使我的代码正常工作。现在最大的问题(根据我得到的评论)是它早已被弃用。也许 boost iostreams 中有一些东西可以提供帮助,但对该库有很多了解。std::ios_base::app
strstream
答:
3赞
vvv444
5/31/2023
#1
与其使用 C++98 中弃用的 strstream
,并且由于编译器中提到的 4GB 限制,您不能使用其标准推荐的替代品(即字符串
流),则可以使用 Boost 的缓冲区流
作为替代方案,如下所示:
#include <iostream>
#include <boost/interprocess/streams/bufferstream.hpp>
namespace bi = boost::interprocess;
int main()
{
std::string buffer("Dummy Data");
bi::bufferstream ss(&buffer[0], buffer.size());
std::string other;
ss >> other;
std::cout << other << std::endl;
return 0;
}
这个类似乎只是头文件,所以不需要编译boost。无论如何,如果使用 Visual Studio,则可以使用 vcpkg 轻松安装 boost。
注意:正如 Peppin 对这个问题的评论中提到的,如果您的数据来自文件,那么与其将其完全读取到内存中,不如只使用内存映射文件。在这个答案中,有一个很好的例子来说明如何做到这一点。
评论
0赞
Lorah Attkins
5/31/2023
这是一个很好的答案,因为该库还包含用于文件映射的跨平台实用程序,根据其中一条评论,这应该是非常大的数据集的可用后备
0赞
vvv444
6/1/2023
@LorahAttkins是的,这个评论是非常正确的。如果您的数据来自文件,则将其完全读取到 RAM 是没有意义的。我只是试着从狭义上回答你的问题。但如果你愿意,我也可以提供文件映射的答案。
0赞
Lorah Attkins
6/1/2023
我陷入了困境,因为我忽略了仅适用于静态缓冲区,但允许使用来填充默认构造的实例,即没有缓冲区的实例(导致 UB)。最终用于动态填充的流,并“避免复制现有缓冲区。顺便说一句,我恢复了 c++11 标签,因为这是我的目标语言标准。如果我没有标准要求,我可以使用它,这不会带来额外的依赖关系。bufferstream
operator<<
vectorstream
bufferstream
std::spanstream
评论
strstream
25 年前被弃用了,你真的不应该使用它std::stringstream
myStream << delimiter << current_data[i] << ...
stream << content
)std::streambuf