在命中文件末尾后回滚ifstream对象

时间:2015-02-04 20:40:48

标签: c++ io ifstream

有一个包含几个字符的文本文件(比方说10),您可以尝试从中读取1000个字符。

char *buf = new char[1000];
ifstream in("in.txt");
in.read(buf, 1000);

这当然会设置eofbit标志(以及failbit),但是,您将能够获得所需的字符。

现在,假设您想再次(从头开始)读取文件:

in.seekg(0);        // Sets input position indicator. 
in.read(buf, 100);  // Try to read again.

如果你致电

,这不起作用
int count = in.gcount()  // Charecters readed from input.

你会注意到count == 0。这意味着它根本没有任何进展。

因此问题是:如何在命中文件结束后重新启动文件?

1 个答案:

答案 0 :(得分:37)

解决方案

在致电seekg之前,使用clear清除ifstream的状态。 请务必先检查您是否需要稍后了解状态。

in.clear();
in.seekg(0);

解释

seekg设置输入位置,但清除状态位failbit因此,ifstream实例“认为”还有错误。

从标准规范:

  

std :: basic_istream :: seekg 的行为为UnformattedInputFunction,但gcount()不受影响。

我们可以阅读UnformattedInputFunction

  

以下标准库函数是 UnformattedInputFunctions

     

basic_istream :: seekg 首先清除eofbit 并且不修改gcount

在问题示例中,如果您在搜索之前和之后打印状态,则获得:

cout << "State before seekg: " << in.rdstate() << endl;   // Prints 3 (11 in binary) failbit and eofbit activated.
in.seekg(0);
cout << "State after seekg: " << in.rdstate() << endl;    // Prints 2 (10 in binary) just failbit activated.

这就是为什么!!

seekg不清除failbit,并且由于某些实现原因,它不适用于这样的位激活。

我的猜测

激活failbit时,为什么seegk不起作用?

这与事实有关,这个位不仅在流到达文件末尾时被激活。并且可能是在激活failbit之后,使用gseek容易出错或者可能显示未定义的行为。