如何在不复制或查找的情况下获取 const 字符串流缓冲区的长度?
How can I obtain the length of a const stringstream's buffer without copying or seeking?
我有一个const std::stringstream
,并希望找出其底层字符串缓冲区中有多少字节。
-
我不能
seekg
到最后,tellg
然后seekg
再次开始,因为这些操作都不可用const
。 -
我不想获得
str().size()
,因为str()
返回一个副本,这可能不是微不足道的数据量。
我有什么好的选择吗?
(流本身以const
的形式呈现给我,只是因为它是另一种类型的成员,并且我收到对该类型对象的const
引用。流表示"文档"的内容,其封装对象表示 CGI 响应,我正在尝试从 operator<<(std::ostream&, const cgi_response&)
中生成准确的 Content-Length
HTTP 标头行。
我对流缓冲区从来都不是很满意,但这似乎对我有用:
#include <iostream>
#include <sstream>
std::stringstream::pos_type size_of_stream(const std::stringstream& ss)
{
std::streambuf* buf = ss.rdbuf();
// Get the current position so we can restore it later
std::stringstream::pos_type original = buf->pubseekoff(0, ss.cur, ss.out);
// Seek to end and get the position
std::stringstream::pos_type end = buf->pubseekoff(0, ss.end, ss.out);
// Restore the position
buf->pubseekpos(original, ss.out);
return end;
}
int main()
{
std::stringstream ss;
ss << "Hello";
ss << ' ';
ss << "World";
ss << 42;
std::cout << size_of_stream(ss) << std::endl;
// Make sure the output string is still the same
ss << "nnew line";
std::cout << ss.str() << std::endl;
std::string str;
ss >> str;
std::cout << str << std::endl;
}
关键是rdbuf()
const
但返回一个非常量缓冲区,然后可以使用该缓冲区进行查找。
如果您想知道剩余的可用输入大小:
#include <iostream>
#include <sstream>
std::size_t input_available(const std::stringstream& s)
{
std::streambuf* buf = s.rdbuf();
std::streampos pos = buf->pubseekoff(0, std::ios_base::cur, std::ios_base::in);
std::streampos end = buf->pubseekoff(0, std::ios_base::end, std::ios_base::in);
buf->pubseekpos(pos, std::ios_base::in);
return end - pos;
}
int main()
{
std::stringstream stream;
// Output
std::cout << input_available(stream) << std::endl; // 0
stream << "123 ";
std::cout << input_available(stream) << std::endl; // 4
stream << "567";
std::cout << input_available(stream) << std::endl; // 7
// Input
std::string s;
stream >> s;
std::cout << input_available(stream) << std::endl; // 4
stream >> s;
std::cout << input_available(stream) << std::endl; // 0
}
这类似于@Cornstalks解决方案,但正确定位了输入序列。
这应该:)工作)
#include <iostream>
#include <sstream>
#include <boost/move/move.hpp>
int main()
{
const std::stringstream ss("hello");
std::cout << boost::move(ss).str().size();
}