当使用("some content",std :: ios :: in | std :: ios :: ate)构造std :: stringstream时,tellg()的预期行为是什么?

Wer*_*mus 6 c++ iostream libstdc++ c++11

我有以下代码令我感到惊讶(使用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;
}
Run Code Online (Sandbox Code Playgroud)

...具有以下输出.

tellg()pos:0

此行为与使用std :: ifstream(std :: ios :: ate)时不同.

  • 这种行为是正确/预期的吗?
  • 尽管打开了吃饭,是否需要明确地寻求(0,std :: ios :: end)?
  • 清除国家并没有什么不同.
  • 请注意,字符串包含内容.

Ser*_*eyA 2

这完全符合标准告诉我们的内容。以下是相关详情:

您使用的构造函数的版本:

通过调用 std::basic_streambuf 的默认构造函数构造一个 std::basic_stringbuf 对象,用空字符串初始化字符序列,并设置模式,然后像调用 str(new_str) 一样初始化关联的字符序列。

默认构造函数basic_stringbuf在这里并不有趣,并且比std::basic_stringbuf::str

删除此 std::basic_stringbuf 的整个底层字符序列,然后配置一个包含 s 内容副本的新底层字符序列。...对于附加流(mode & ios_base::ate == true),pptr() == pbase() + s.size(),以便后续输出将附加到从 s 复制的最后一个字符

最后,tellg()调用pubseekoff缓冲区:

如果其中包含 ios_base::in 并且此缓冲区打开以供读取(即 if ((which & ios_base::in) == ios_base::in),则重新定位读取指针 std::basic_streambuf::gptr: 。 .那么newoff是指针的当前位置(在本例中为gptr()-eback())

总结一下:由于您没有以任何方式修改 get 位置(构造函数仅修改 put 位置),因此它返回 0。