How does feof () really know when the end of file is reached?

I am new to C ++ and try to better understand feof() . I read that the feof() flag is set to true only after you try to read beyond the end of the file so many times that beginners will read again than expected if they do something like while(!feof(file)) . What I'm trying to understand is how it actually interprets that an attempt was made to read the end of the file? Already read the entire file and the number of already known characters, or is there some other mechanism at work?

I understand that this may be a duplicate question somewhere, but I could not find it, probably because I do not know how best to say what I ask. If there is already an answer, the link will be much appreciated. Thank you

+6
source share
5 answers

No matter what the C ++ library does, in the end it should read from a file. Somewhere in the operating system there is a piece of code that ultimately handles this reading. It gets the file length from the file system, keeping the same as the file system storing everything else. Knowing the length of the file, the reading position, and the number of bytes read, he can determine that low-level reading falls at the end of the file.

When this determination is made, it is pushed onto the stack. In the end, he gets into the standard library, which internally records that the end of the file has been reached. When a read request to the library tries to get past this written end, the EOF flag is set and feof will start returning true.

+10
source

feof() is part of the standard buffered C / I library. Since it is buffered, fread() pre-reads some data (specifically, not the entire file). If fread() detects EOF during buffering (the base OS procedure returns a special value, usually -1 ), it sets a flag in the FILE structure. feof() just checks this flag. So feof() returning true essentially means "previous read attempt found at the end of the file."

How EOF is detected depends on the OS / FS and has nothing to do with the C library / language. The OS has some interface for reading data from files. The C library is just a bridge between the OS and the program, so you do not need to change your program if you switch to another OS. The OS knows how files are stored in its file system, so it knows how to detect EOF. I suppose this is usually done by comparing the current position with the length of the file, but it may not be that simple and may include many low-level details (for example, what if the file is on a network drive?).

An interesting question is what happens when the stream is at the end, but it has not yet been detected while reading. For example, if you open an empty file. The first call to feof() before any fread() returns true or false? The answer is probably incorrect. Documents are not very clear on this issue:

This indicator is usually set by the previous operation in the stream that was attempted to be read at or near the end of the file.

It seems that a particular implementation may choose other unusual ways to set this flag.

+8
source

Most of the file system supports meta-information about the file (including its size) and an attempt to read the end results in flag flags. Others, such as old or lightweight file systems, install feof when they arrive at the last byte of the last block in the chain.

+3
source

How does feof () really know when the end of file is reached?

When the code tries to read the past character.

Depending on the type of file, the last character is necessarily known until an attempt is made to read it and the character is not available.


Code sample showing feof() going from 0 to 1

 #include <stdio.h> void ftest(int n) { FILE *ostream = fopen("tmp.txt", "w"); if (ostream) { while (n--) { fputc('x', ostream); } fclose(ostream); } FILE *istream = fopen("tmp.txt", "r"); if (istream) { char buf[10]; printf("feof() %d\n", feof(istream)); printf("fread %zu\n", fread(buf, 1, 10, istream)); printf("feof() %d\n", feof(istream)); printf("fread %zu\n", fread(buf, 1, 10, istream)); printf("feof() %d\n", feof(istream)); puts(""); fclose(istream); } } int main(void) { ftest(9); ftest(10); return 0; } 

Exit

 feof() 0 fread 9 // 10 character read attempted, 9 were read feof() 1 // eof is set as previous read attempted to read passed the 9th or last char fread 0 feof() 1 feof() 0 fread 10 // 10 character read attempted, 10 were read feof() 0 // eof is still clear as no attempt to read passed the 10th, last char fread 0 feof() 1 
+2
source

The feof() function sets the end-of-file character when the EOF character is read. Therefore, when feof() reads the last element, EOF is not read at first with it. Since no EOF indicator is set, and feof() returns zero, the stream returns to the while loop again. This time, fgets finds out that the next character is EOF, discards it and returns NULL, but also sets the EOF indicator. Thus, feof() detects the end-of-file indicator and returns a nonzero value, so it aborts the while loop.

-2
source

All Articles