打印出ostringstream缓冲区

print out ostringstream buffer

本文关键字:缓冲区 ostringstream 打印      更新时间:2023-10-16

这里有一段简单的代码,应该打印一个std::ostringstream缓冲区,而这个缓冲区又是通过rdbuf()获得的。我希望这个缓冲区通过istreambuf迭代器或直接通过<<运算符打印到std::cout。令人惊讶的是,没有什么可以打印这个缓冲区。更有趣的是,<<运算符清除了这个缓冲区。

#include <iostream>
#include <sstream>
#include <algorithm>
#include <iterator>
using namespace std;
int main()
{
std::ostringstream buf_ref;
buf_ref << "bgdgdgdfg" << std::endl;
auto buff = buf_ref.rdbuf();

std::cout << "1 " << buf_ref.str() << std::endl;
std::copy(std::istreambuf_iterator<char>(buff), std::istreambuf_iterator<char>(), std::ostream_iterator<char>(std::cout));
std::cout << "2 " << buf_ref.str() << std::endl;
std::cout << buff << std::endl; /*Why it clears the buffer? Why it doesn't output anything?*/
std::cout << "3 " << buf_ref.str() << std::endl;
return 0;
}

你知道这里出了什么问题吗?BTS,这里是描述<lt;streambuf*的运算符过载cplusplus.com/reference/osteream/ostream/operator%3C%3C因此,它应该是要打印的streambuf的一个内容。

<操作员清除这个缓冲区。

好吧,<<从流单元中读取数据,当流变空时,默认情况下它会将数据块读取到第一个空白。

令人惊讶的是,没有什么可以打印这个缓冲区。

最简单的方法是使用buff.str()打印出内容。通过这种方式,您可以获得数据的副本,因此它不会从原始流中删除。

我希望这个缓冲区打印到std::cout

也许这个小例子会揭示它的工作机制。

stringstream buf;
streambuf *backup;
backup = cout.rdbuf();
cout.rdbuf(buf.rdbuf());
buf << "normal buf" << endl;
cout << "cout to buf" << endl;
cout.rdbuf(backup);
cout << "normal cout" << endl;
cout << buf.str() << endl;

这导致以下输出:

normal cout
normal buf
cout to buf

但你可能指的是类似的功能:

stringstream buf;
streambuf *ptr;
ptr = buf.rdbuf();
// cout << buf.rdbuf(); // if you do it, check error state flags
// cout.clear(); // and/or clear it
buf << 'A' << endl;
cout << buf.rdbuf();
buf << 'B' << endl;
cout << ptr;

打印出来的:

A
B

如果您的目标是通过其rdbuf()成员打印输出字符串流的流缓冲区,那么这将不起作用。无法将输出字符串流缓冲区转换为输入字符串流缓冲区时,因为openmode是在构造时设置的,因此无法更改。如果流是为输出而打开的(在字符串流上(,则它不能用于输入,反之亦然。您必须将所有内容复制到std::istringstreamstd::stringbuf中。

std::ostringstream oss("abc");
std::istringstream iss(oss.str()); // 1
std::stringbuf buffer(oss.str()); // 2
std::cout << iss.rdbuf(); // 1
std::cout << &buffer; // 2

或者只使用std::stringstream