我有以下代码让我感到惊讶(使用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)时不同。
答案 0 :(得分:2)
这完全符合标准告诉我们的内容。以下是相关细节:
您使用的构造函数的版本:
通过调用std :: basic_streambuf的默认构造函数构造一个std :: basic_stringbuf对象,用空字符串初始化字符序列,并设置模式,然后初始化关联的模式 字符序列,如同调用str(new_str)。
basic_stringbuf
的默认构造函数在这里并不重要,而不是std::basic_stringbuf::str
:
删除此基础的整个基础字符序列 std :: basic_stringbuf然后配置一个新的底层字符 包含s内容副本的序列。 ...追加 streams(mode&amp; ios_base :: ate == true),pptr()== pbase()+ s.size(), 以便后续输出将附加到最后一个字符 从s
复制而来
最后,tellg()
,在缓冲区上调用pubseekoff
:
如果包含ios_base :: in,则此缓冲区已打开以供阅读 (即if((&amp; ios_base :: in)== ios_base :: in),然后 重新定位读指针std :: basic_streambuf :: gptr:..然后newoff是指针的当前位置(在这种情况下为gptr() - eback())
总结一下:由于你没有以任何方式修改获取位置(构造函数只修改了put位置),它返回0.
答案 1 :(得分:2)
tellg()
返回gptr()-eback()
并在ios_base::in
中提供stringstream
标记(因此basic_stringbuf
)构造函数具有后置条件gptr() == eback()
。
因此,0
是预期/强制执行的。
tellg()
返回rdbuf()->pubseekoff(0, std::ios_base::cur, std::ios_base::in)
rdbuf()
返回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
返回gptr()-eback()
eback()
返回指向get区域开头的指针gptr()
返回当前获取点 stringstream
初始化:
basic_stringstream (basic_string const &str, ios_base::openmode which);
效果:构造类basic_stringstream的对象,使用
basic_iostream(&sb)
初始化基类并使用basic_stringbuf(str, which)
初始化sb。
basic_stringbuf(basic_string const &str, ios_base::openmode which)
效果:构造类basic_stringbuf的对象,使用
basic_streambuf()
初始化基类,并使用初始化模式。然后拨打str(s)
。
void basic_stringbuf::str(const basic_string<charT,traits,Allocator>& s);
效果:将s的内容复制到basic_stringbuf基础字符序列中,并根据模式初始化输入和输出序列。
后置条件:
如果
mode & ios_base::out
为true
,则pbase()
指向第一个基础字符,epptr() >= pbase() + s.size()
成立;如果
mode & ios_base::ate
为true
,则pptr() == pbase() + s.size()
成立,否则pptr() == pbase()
为true
。如果
mode & ios_base::in
为true
,则eback()
指向第一个基础角色,而gptr() == eback()
和egptr() == eback() + s.size()
都会成立。
最后一位是相关的:提供ios_base::in
有后置条件gptr() == eback()
,而tellg()
返回gptr()-eback()
后,结果必须为零。