Istream seekg()偏移量和ios::end

3

当我输入is.seekg(0)时,它会将我的流定位到开头。但是,当我输入is.seekg(ios::end)时,它会将我定位到第二个字符。为什么会发生这种情况?我认为我对此的误解根源在于我对流如何工作的基本理解不足。我认为当您提供常量ios::end时,它应该将您带到该流的末尾。但是,似乎它会将您向前移动一个字符。

  cin.seekg(0, ios::end);
  int length = cin.tellg();
  cout << length << endl;

  cin.seekg(0);

  cout << cin.tellg();

当我输入一个包含"123456789"的文件 < 时,
输出结果是10 0。
现在如果我这样做:
  cin.seekg(ios::end);
  int length = cin.tellg();
  cout << length << endl;

输出结果为2。

为什么会是2?

3个回答

4
这段代码仅仅是偶然运行成功的。
cin.seekg(ios::end);
int length = cin.tellg();
cout << length << endl; 

end 来自一个枚举类型 enum seekdir {beg, cur, end};,因此 ios::end 恰好可以转换为一个整数,其值为 2

可惜的是,seekg 的某个重载函数的参数是一个整数,所以这个调用变成了 cin.seekg(2)。虽然在技术上是有效的代码,但这绝不是你想要的。


2
你正在将类型为std::ios_base :: seekdir的内容转换为类型std::istream :: pos_type,并调用只带一个参数的版本seekg。该版本的seekg将指针移动到绝对位置而不是相对位置。 ios :: end是用于相对偏移的逻辑位置,而不是绝对位置。

1

您不能依赖于 STDIN 可以被寻址。这是因为它可以来自许多来源,包括绝对不可寻址的管道。当您将文件重定向时,STDIN 与文件流相关联,所以它可能会起作用。我不知道您是否可以依赖于它,但那是我的猜测。我从未考虑过在 STDIN 上寻址。即使它不是管道,我也总是将其视为管道。STDOUT 也是如此。我不会输出某些内容,然后尝试回溯并“覆盖”该输出。如果您发现自己需要在标准流中寻址,则应重新考虑您的方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接