3

std::stringbuf 的pubsetbuf成员在 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成员。

4

4 回答 4

4

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

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

如果您需要一个在其外部的字符串上工作的流,请考虑std::strstream:或boost::iostreams::array_sink

于 2012-04-07T12:20:23.683 回答
3

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

输出“再见!”

于 2012-12-05T04:22:56.067 回答
0

我看到同样的事情。我正在处理绝对不能制作不必要的数据副本的场景。根据 basic_streambuf 类中的评论,这似乎是有意的:

virtual basic_streambuf *__CLR_OR_THIS_CALL setbuf(_Elem *, streamsize)
    {   // offer buffer to external agent (do nothing)
    return (this);
    }
于 2018-03-23T02:37:14.497 回答
0

我最近遇到了相同的 setbuf 未在 Visual Studio 2017 中实现的问题。

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

输出流

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

#include <streambuf>

模板 <typename char_type>
结构 ostreambuf : 公共 std::basic_streambuf<char_type, std::char_traits<char_type> >
{
    ostreambuf(char_type* 缓冲区,std::streamsize bufferLength)
    {
        // 将“put”指针设置为缓冲区的开头并记录它的长度。
        设置(缓冲区,缓冲区+缓冲区长度);
    }
};

输入流

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

#include <streambuf>

模板 <typename char_type>
结构 istreambuf : public basic_streambuf<char_type, char_traits<char_type>>
{
    istreambuf(char_type* 缓冲区,streamsize 缓冲区长度)
    {
        // 将“get”指针设置为缓冲区的开头,即下一项,并记录其长度。
        this->setg(buffer, buffer, buffer + buffer_length);
    }
};

主函数()
{
    ifstream infile(FILENAME, ifstream::binary);

    // 将整个文件读入缓冲区。
    infile.seekg(0, ios::end);
    streampos 长度 = infile.tellg();
    infile.seekg(0, ios::beg);
    向量<char> 缓冲区(长度);
    //char* 缓冲区 = new char[length];
    infile.read(&buffer[0], 长度);
    infile.close();

    // 创建缓冲区并将 local_stream 指向它。
    istreambuf<char> istream_buffer(&buffer[0], 长度);
    istream local_stream(&istream_buffer);

    字符串 str1;

    而 (local_stream >> str1)
    {
        . . .
    }
}
于 2019-05-27T14:40:35.483 回答