Visual Studio std::stringstream pubsetbuf 不起作用

Visual Studio std::stringstream pubsetbuf does not work

本文关键字:pubsetbuf 不起作用 stringstream Visual std Studio      更新时间:2023-10-16

pubsetbuf std::stringbuf 的成员在 Visual Studio 2010 中根本不起作用!

代码:

char *FileData = ... ;
unsigned long long FileDataLen = ... ;
std::stringstream *SS = new std::stringstream(std::stringstream::in | std::stringstream::out);
SS->rdbuf()->pubsetbuf( FileData, (std::streamsize)FileDataLen );

pubsetbuf 在 Visual Studio 中什么都不做!!

解决方法 #1

std::stringstream *SS = new std::stringstream( std::string(FileData, (size_type)FileDataLen ) ),std::stringstream::in | std::stringstream::out);

解决方法 #2

SS->rdbuf()->sputn(FileData, (streamsize)FileDataLen);

但这两种解决方法都会产生不必要的内存复制。我绝对需要一个 std::stringbuf 的 pubsetbuf 成员。

putsetbuf只对fstream有意义(从技术上讲,对于std::basic_filebuf),其中缓冲区和流是两个不同的东西。

对于stringstream(技术上,std::basic_stringbuf),它们是同一个std::string。

如果需要处理外部字符串的流,请考虑std::strstream : 或 boost::iostreams::array_sink

basic_ios.clear()如果您需要更改 rdbuf,请先调用它,否则它将无法工作。

std::ifstream file("file1.txt"); // file1.txt contains "Welcome!"
std::stringstream ss;
ss << file.rdbuf();
std::cout << ss.str() << std::endl;

输出"欢迎!
让我们使用新文件重试。

// Empty it
file.close();
ss.str("");
// New file
file.open("file2.txt"); // file2.txt contains "Goodbye!"
ss << file.rdbuf();
std::cout << ss.str() << std::endl;

不输出任何内容。

ss.clear();
ss << file.rdbuf();
std::cout << ss.str() << std::endl;
file.close();

输出"再见!

我看到了同样的事情。我正在处理绝对负担不起制作不必要的数据副本的方案。根据basic_streambuf类中的评论,这似乎是故意的:

virtual basic_streambuf *__CLR_OR_THIS_CALL setbuf(_Elem *, streamsize)
    {   // offer buffer to external agent (do nothing)
    return (this);
    }

>我最近遇到了同样的问题,即在Visual Studio 2017中没有实现setbuf。

在对 Stack Overflow 进行一些搜索后,我找到了一种输出流的解决方案,该解决方案不使用我为输入流修改的缓冲区的复制。这里供参考。

输出流

源:设置标准流使用的内部缓冲区 (pubsetbuf)

 #include<流布夫>模板 <类型名称&nbsp;char_type> 结构 ostreambuf : 公共 标准::basic_streambuf<char_type,&nbsp;标准::&nbsp;char_traits> >{    ostreambuf(char_type* buffer, std::streamsize bufferLength)    {          将"放置" 指针  设置为 缓冲区 的  开头 并 记录 其 长度。        setp(buffer, buffer + bufferLength );    }};

输入流

源:标准输入流 (pubsetbuf) 使用的内部缓冲区

 #include<流布夫>模板 <类型名称&nbsp;char_type> 结构 istreambuf : 公共 basic_streambuf<char_type,&nbsp;char_traits>>{    istreambuf(char_type* buffer, streamsize buffer_length)    {         将 "get" 指针 设置为   缓冲区的  开头 ,下一项 ,   并 记录 其 长度。        this->setg(buffer, buffer,  buffer + buffer_length);    }}; int main(){    ifstream infile(FILENAME, ifstream ::binary);     将整个 文件 读入  缓冲区。    infile.seekg(0, ios::end);    streampos length = infile.tellg();    infile.seekg(0, ios::beg);    向量<字符> 缓冲区(长度);    字符* 缓冲区 = 新 字符[长度];    infile.read(&buffer[0], length);    infile.close();     创建 缓冲区 并将 local_stream  指向 它。    istreambuf istream_buffer(&buffer[0], length);    istream local_stream(&istream_buffer);    字符串 str1;    而 (local_stream>>  str1)    {        . . .    }}