【问题标题】:failbit not being set when seekg seeks past end of file (C++,Linux)当 seekg 查找文件末尾(C++,Linux)时未设置故障位
【发布时间】:2012-06-16 20:32:15
【问题描述】:

我看到了我认为 istream::seekg 的奇怪行为。具体来说,似乎 当我寻找明显远离文件末尾的点时,不要设置故障位。

从我在文档中可以看出,应该设置故障位,但事实并非如此。

谁能解释这种行为?相关代码的sn-p:

class Tester 
{

  ... 

  void testTriggered()
  {
    fs.open("/pathtofile/testFile.TEST", std::ios_base::in|std::ios_base::binary);
    prv_testbits("testTriggered(): OpeningFile");

    fs.seekg(2000,std::ios_base::beg);
    prv_testbits("testTriggered(): seekTwoThousand");
    int g = fs.tellg();
    std::cout << "get pointer is:" << g << std::endl; 
  }

  void prv_testbits(std::string msg){
    if (fs.fail()) {
      std::cout << msg << ": failbit set." << std::endl;
    } else {
      std::cout << msg << ": failbit NOT set." << std::endl;
    }
    if (fs.bad()) {
      std::cout << msg << ": badbit set." << std::endl;
    }else {
      std::cout << msg << ": badbit NOT set." << std::endl;
    }
    if (fs.eof()) {
      std::cout << msg << ": eofbit set." << std::endl;
    } else {
      std::cout << msg << ": eofbit NOT set." << std::endl;
    }
  }

   ....

 private:
  std::ifstream fs;
}; 

输入文件由二十个字节组成: 0123456789abcdefghij

样本运行的输出:

testTriggered(): OpeningFile: failbit NOT set.
testTriggered(): OpeningFile: badbit NOT set.
testTriggered(): OpeningFile: eofbit NOT set.
testTriggered(): seekTwoThousand: failbit NOT set.
testTriggered(): seekTwoThousand: badbit NOT set.
testTriggered(): seekTwoThousand: eofbit NOT set.
get pointer is:2000

g++ 版本信息: $ g++ -v 使用内置规范。 目标:x86_64-linux-gnu 配置:../src/configure -v --with-pkgversion='Ubuntu 4.4.3-4ubuntu5' -with-gxx-include-dir=/usr/include/c++/4.4 [snip] gcc 版本 4.4.3 (Ubuntu 4.4.3-4ubuntu5)

$ unname -a Linux hostx 2.6.32-36-server #79-Ubuntu SMP Tue Nov 8 22:44:38 UTC 2011 x86_64 GNU/Linux

【问题讨论】:

  • 欢迎来到 SO!您写道,“从我在文档中可以看出......”您正在查阅哪些文档,它说了什么?
  • 流中的错误标志通常在尝试读/写操作失败时设置。输出“2000”表示对 seekg() 的调用成功 - 设置了 get 指针,只是没有指向有效位置。
  • 是的,你猜对了,我使用 cpluspplus.com 作为我的文档。我开始认为文档可能是错误的,它表明应该在调用 seekg 后设置故障位。但是,cppreference.com 并未表明这一点。
  • 我对 cplusplus.com 的文档的阅读表明,如果“参数描述了无法到达的位置”,则设置了 failbit。这不会收缩您所看到的行为。由于通常允许在文件末尾之外进行搜索 - 如果您随后在该位置写入,它只会扩展文件的大小 - 可以到达您指定的位置(2000)。
  • 有人可能会争辩说,由于我以只读方式打开文件,因此可能永远不会到达第 2000 个位置,除非其他人写入该文件:) 但是,我认为底线是只是 seekg() 在这种情况下没有设置故障位。

标签: c++


【解决方案1】:

fseek()(可能用于实现fstream::seekg)的开放组规范要求允许文件位置超出当前文件结尾:

fseek() 函数应允许将文件位置指示器设置在文件中现有数据的末尾之外。如果此时稍后写入数据,则后续读取间隙中的数据应返回值为 0 的字节,直到数据实际写入间隙。

http://pubs.opengroup.org/onlinepubs/009696699/functions/fseek.html

【讨论】:

  • 是的,这符合 seekg 的行为方式。感谢您的反馈!
猜你喜欢
  • 2018-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-24
  • 1970-01-01
  • 2015-10-10
  • 1970-01-01
  • 2013-01-25
相关资源
最近更新 更多