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

Ray*_*nda 15 c++ io ifstream

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

char *buf = new char[1000];
ifstream in("in.txt");
in.read(buf, 1000);
Run Code Online (Sandbox Code Playgroud)

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

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

in.seekg(0);        // Sets input position indicator. 
in.read(buf, 100);  // Try to read again.
Run Code Online (Sandbox Code Playgroud)

如果你打电话,这不起作用

int count = in.gcount()  // Charecters readed from input.
Run Code Online (Sandbox Code Playgroud)

你会注意到的count == 0.这意味着它根本没有任何内容.

因此问题是:如何在文件结束后重新打开文件?

Ray*_*nda 41

在通话前使用clear清除 ifstream的状态seekg.如果您不需要先了解状态,请务必先检查.

in.clear();
in.seekg(0);
Run Code Online (Sandbox Code Playgroud)

说明

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

从标准规范:

std :: basic_istream :: seekg表现为UnformattedInputFunction,但gcount()不受影响.

我们可以在UnformattedInputFunction中读取:

以下标准库函数是UnformattedInputFunctions:

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

在问题示例中,如果您在seekg之前和之后打印状态,则会得到:

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.
Run Code Online (Sandbox Code Playgroud)

这就是为什么!!

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

我猜

seegkfailbit被激活时,为什么不起作用?

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