【问题标题】:Visual Studio std::stringstream pubsetbuf does not workVisual Studio std::stringstream pubsetbuf 不起作用
【发布时间】:2012-04-20 17:10:27
【问题描述】:

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 成员。

【问题讨论】:

    标签: c++ visual-studio stl std


    【解决方案1】:

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

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

    输出流

    来源:Setting the internal buffer used by a standard stream (pubsetbuf)

    #include 模板 结构 ostreambuf : public std::basic_streambuf { ostreambuf(char_type* buffer, std::streamsize bufferLength) { // 将“放置”指针设置为缓冲区的开始并记录它的长度。 setp(缓冲区,缓冲区+缓冲区长度); } };

    输入流

    来源:Internal buffer used by standard input stream (pubsetbuf)

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

    【讨论】:

    • 虽然这些链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接的答案可能会失效。
    • @Johan,感谢您的建议。我添加了一些代码 sn-ps。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案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();
      

      输出“再见!”

      【讨论】:

        【解决方案4】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-09-10
          • 1970-01-01
          • 2018-12-03
          • 1970-01-01
          • 1970-01-01
          • 2010-12-04
          • 1970-01-01
          • 2013-03-13
          相关资源
          最近更新 更多