当 std::stringstream 由 ("some content", std::ios::in|std::ios::ate) 构造时,tellg() 的预期行为是什么?
What is the expected behavior of tellg() when std::stringstream is constructed with ("some content", std::ios::in|std::ios::ate)?
我有以下一段代码让我感到惊讶(使用 libstdc++4.8)...
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
std::string s("some content");
std::stringstream ss(s, std::ios::in|std::ios::ate);
std::istream& file = ss;
//ss.clear(); Makes no difference...
std::cout << "tellg() pos: " << file.tellg() << std::endl;
return 0;
}
... 具有以下输出。
tellg() pos: 0
此行为与使用 std::ifstream(std::ios::ate) 时不同。
- 这种行为是 correct/expected 吗?
- 尽管用 ate 打开,是否需要显式 seekg(0, std::ios::end)?
- 清除状态没有区别。
- 请注意字符串有内容。
这完全符合标准告诉我们的内容。以下是相关详情:
您使用的构造器版本:
Constructs a std::basic_stringbuf object by calling the default constructor of std::basic_streambuf, initializes the character sequence with an empty string, and sets the mode to which, than followed by initializing the associated
character sequence as if by calling str(new_str).
basic_stringbuf
的默认构造函数在这里并不有趣,比 std::basic_stringbuf::str
:
Deletes the entire underlying character sequence of this
std::basic_stringbuf and then configures a new underlying character
sequence containing a copy of the contents of s. ... For append
streams (mode & ios_base::ate == true), pptr() == pbase() + s.size(),
so that subsequent output will be appended to the last character
copied from s
最后,tellg()
,它在缓冲区上调用 pubseekoff
:
If which includes ios_base::in and this buffer is open for reading
(that is, if ((which & ios_base::in) == ios_base::in), then
repositions the read pointer std::basic_streambuf::gptr: .. then newoff is the current position of the pointer (gptr()-eback() in this case)
总结一下:因为你没有以任何方式修改 get 位置(构造函数只修改 put 位置),它 returns 0.
简而言之:
tellg()
returns gptr()-eback()
并在 stringstream
(因此 basic_stringbuf
)构造函数中提供 ios_base::in
标志具有后置条件gptr() == eback()
.
因此,0
是预期/强制执行的。
长:
tellg()
returns rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)
rdbuf()
returns const_cast<basic_stringbuf*>(&sb)
.
pubseekoff(0, std::ios_base::cur, std::ios_base::in)
呼叫 seekoff(0, std::ios_base::cur, std::ios_base::in)
seekoff
returns gptr()-eback()
eback()
returns指向获取区开始的指针
gptr()
returns当前获得点数
stringstream
初始化:
basic_stringstream (basic_string const &str, ios_base::openmode which);
Effects: Constructs an object of class basic_stringstream, initializing the base class with basic_iostream(&sb)
and initializing sb with basic_stringbuf(str, which)
.
basic_stringbuf(basic_string const &str, ios_base::openmode which)
Effects: Constructs an object of class basic_stringbuf, initializing the base class with basic_streambuf()
, and initializing mode with which. Then calls str(s)
.
void basic_stringbuf::str(const basic_string<charT,traits,Allocator>& s);
Effects: Copies the content of s into the basic_stringbuf underlying character sequence and initializes the input and output sequences according to mode.
Postconditions:
If mode & ios_base::out
is true
, pbase()
points to the first underlying character and epptr() >= pbase() + s.size()
holds;
if mode & ios_base::ate
is true
, pptr() == pbase() + s.size()
holds, otherwise pptr() == pbase()
is true
.
If mode & ios_base::in
is true
, eback()
points to the first underlying character, and both gptr() == eback()
and egptr() == eback() + s.size()
hold.
最后一位相关:提供 ios_base::in
具有后置条件 gptr() == eback()
并且由于 tellg()
returns gptr()-eback()
结果需要为零.
我有以下一段代码让我感到惊讶(使用 libstdc++4.8)...
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
std::string s("some content");
std::stringstream ss(s, std::ios::in|std::ios::ate);
std::istream& file = ss;
//ss.clear(); Makes no difference...
std::cout << "tellg() pos: " << file.tellg() << std::endl;
return 0;
}
... 具有以下输出。
tellg() pos: 0
此行为与使用 std::ifstream(std::ios::ate) 时不同。
- 这种行为是 correct/expected 吗?
- 尽管用 ate 打开,是否需要显式 seekg(0, std::ios::end)?
- 清除状态没有区别。
- 请注意字符串有内容。
这完全符合标准告诉我们的内容。以下是相关详情:
您使用的构造器版本:
Constructs a std::basic_stringbuf object by calling the default constructor of std::basic_streambuf, initializes the character sequence with an empty string, and sets the mode to which, than followed by initializing the associated character sequence as if by calling str(new_str).
basic_stringbuf
的默认构造函数在这里并不有趣,比 std::basic_stringbuf::str
:
Deletes the entire underlying character sequence of this std::basic_stringbuf and then configures a new underlying character sequence containing a copy of the contents of s. ... For append streams (mode & ios_base::ate == true), pptr() == pbase() + s.size(), so that subsequent output will be appended to the last character copied from s
最后,tellg()
,它在缓冲区上调用 pubseekoff
:
If which includes ios_base::in and this buffer is open for reading (that is, if ((which & ios_base::in) == ios_base::in), then repositions the read pointer std::basic_streambuf::gptr: .. then newoff is the current position of the pointer (gptr()-eback() in this case)
总结一下:因为你没有以任何方式修改 get 位置(构造函数只修改 put 位置),它 returns 0.
简而言之:
tellg()
returns gptr()-eback()
并在 stringstream
(因此 basic_stringbuf
)构造函数中提供 ios_base::in
标志具有后置条件gptr() == eback()
.
因此,0
是预期/强制执行的。
长:
tellg()
returnsrdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)
rdbuf()
returnsconst_cast<basic_stringbuf*>(&sb)
.pubseekoff(0, std::ios_base::cur, std::ios_base::in)
呼叫seekoff(0, std::ios_base::cur, std::ios_base::in)
seekoff
returnsgptr()-eback()
eback()
returns指向获取区开始的指针gptr()
returns当前获得点数
stringstream
初始化:
basic_stringstream (basic_string const &str, ios_base::openmode which);
Effects: Constructs an object of class basic_stringstream, initializing the base class with
basic_iostream(&sb)
and initializing sb withbasic_stringbuf(str, which)
.
basic_stringbuf(basic_string const &str, ios_base::openmode which)
Effects: Constructs an object of class basic_stringbuf, initializing the base class with
basic_streambuf()
, and initializing mode with which. Then callsstr(s)
.
void basic_stringbuf::str(const basic_string<charT,traits,Allocator>& s);
Effects: Copies the content of s into the basic_stringbuf underlying character sequence and initializes the input and output sequences according to mode.
Postconditions:
If
mode & ios_base::out
istrue
,pbase()
points to the first underlying character andepptr() >= pbase() + s.size()
holds;if
mode & ios_base::ate
istrue
,pptr() == pbase() + s.size()
holds, otherwisepptr() == pbase()
istrue
.If
mode & ios_base::in
istrue
,eback()
points to the first underlying character, and bothgptr() == eback()
andegptr() == eback() + s.size()
hold.
最后一位相关:提供 ios_base::in
具有后置条件 gptr() == eback()
并且由于 tellg()
returns gptr()-eback()
结果需要为零.