Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
657 views
in Technique[技术] by (71.8m points)

c++ - Rewind an ifstream object after hitting the end of file

Having a text file with a few characters (lets say 10), you can try to read 1000 characters from it.

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

This, of course, will set the eofbit flag (and the failbit too), however, you will be able to obtain the desired characters.

Now, suppose you want to read the file again (from the beginning):

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

This does not work: because if you call:

int count = in.gcount()  // Charecters readed from input.

you will notice that count == 0. Meaning it has not read anything at all.

Hence the question: How can you rewind the file after you get to the end of the file?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Solution

Use clear for cleaning the state of the ifstream before call seekg. Be sure to check first if you don't will need to know the state later.

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

Explanation

seekg sets the cursor position, but doesn't clear state bit failbit so, the ifstream instance "thinks" there is something wrong yet.

From the standar specification:

std::basic_istream::seekg behaves as UnformattedInputFunction, except that gcount() is not affected.

And we can read in UnformattedInputFunction:

The following standard library functions are UnformattedInputFunctions:

basic_istream::seekg, except that it first clears eofbit and does not modify gcount

In the question example if you print the state before and after the seekg you get:

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.

That's why!!

seekg doesn't clear failbit and for some implementation reason, it doesn't works with such bit activated.

My guess

Why seekg does not work when failbit is activated?

It has to do with the fact this bit is not only activated when the stream reach the end of the file. And it might be situations in which after failbit is activated, using seekg is error prone or might shows undefined behaviour.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...