This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 6 years ago.
#include <stdio.h>
int main()
{
FILE * fp = fopen("Introduce.txt","rt");
fseek(fp,0,SEEK_END);
int i = feof(fp);
printf("%d",i);
fseek(fp,1,SEEK_END);
i = feof(fp);
printf("%d",i);
fseek(fp,-1,SEEK_END);
i = feof(fp);
printf("%d",i);
return 0;
}
I tried to access EOF positioning 'file position indicator' at the end of the file.
But the result of this code is "000".
Why does this happen?
The feof() function doesn't report that it is at EOF until you try to read some data and there is no data to read.
You can seek beyond the current EOF of a file that's open for writing (or that's open for reading and writing).
See while (!feof(file)) is always wrong for more information on why you seldom if ever need to use feof(). In some ways, feof() is a function you should forget about — most of your programs will improve if you assume it doesn't exist.
This documentation on feof is very clear (emphasis mine):
This function only reports the stream state as reported by the most
recent I/O operation, it does not examine the associated data source.
For example, if the most recent I/O was a fgetc, which returned the
last byte of a file, feof returns zero. The next fgetc fails and
changes the stream state to end-of-file. Only then feof returns
non-zero.
In typical usage, input stream processing stops on any error; feof and
ferror are then used to distinguish between different error
conditions.
Related
This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 11 months ago.
I searched about this problem everywhere, but none of the suggested solutions worked for me.
char currentChar;
FILE *fp_read = fopen("../input.txt", "r");
FILE *fp_write = fopen("../textArranged.txt", "w");
while (!feof(fp_read)){
currentChar = fgetc(fp_read);
...
}
I tried to change the while condition (using getc()), but it didn't work.
feof() seems to return 0 after reading the last byte of the file. It returns 1 after fgetc() already made the attempt to read one more byte after the end of the file.
When fgetc() makes the attempt to read data after the end of the file, fgetc() returns -1.
If you perform fputc(x, ...) and x is not in the range 0...255, fputc() will actually write the byte (x & 0xFF).
On nearly all modern computers, (-1 & 0xFF) is 0xFF which equals the character 'ÿ'.
So the following happens:
...
Your program reads the last byte of the file using fgetc()
It writes that character using fputc()
Although there are no more bytes left in the file, feof() returns 0 because you did not make the attempt to read bytes after the end of the file, yet.
Your program calls fgetc() and because there are no more bytes left, fgetc() returns -1.
Your program calls fputc(-1, ...) which writes the character 'ÿ'.
feof() returns 1 because fgetc() already tried to read bytes after the end of the file.
I just started learning files in c few days ago. In order to understand how to manipulate correctly the functions, I wrote a code who create a new file (w+) read a string and using fputs() put it in the file. Using a function it find how many characters are there. the problem is if I don't rewind before calling the function, the output returned is very large compared to the string the output+string is exactly 4096 every time no matter how big the array. I don't understand why it should just return 0 if I don't rewind the pointer, and why it doesn't return 4096 when I rewind it, instead it returns the correct answer. Here is my code:
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
int daft(FILE* f){
int s=0,c;
while((c=fgetc(f))!=EOF){
if(!isspace(c))
s++;
}
return s;
}
int main(){
char *ch;
ch=malloc(20*sizeof(char));
FILE *f;
f=fopen("test.txt","w+");
if(f!=NULL){
gets(ch);
fputs(ch,f);
printf("n= %d\n",daft(f));
fclose(f);
}
free(ch);
return 0;
}
You need to flush the stream after writing and before reading:
7.21.5.3 The fopen function
...
7 When a file is opened with update mode ('+' as the second or third character in the
above list of mode argument values), both input and output may be performed on the
associated stream. However, output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by output without an
intervening call to a file positioning function, unless the input operation encounters end-of-file. Opening (or creating) a text file with update mode may instead open (or create) a
binary stream in some implementations.
C 2011 Online Draft
Emphasis added. By not flushing after writing and by not rewinding, the stream is not in a good state to be read from. You've entered the realm of undefined behavior - fgetc returns something that's not EOF for many iterations, and as a result s is incremented to a very large value.
This is why it worked when you used the rewind function, because you reset the stream to be in a good state for reading.
EOF is not necessarily stored in the file. Usually, files does not. It is what the function returns when it fails to read.
Also, never use gets()
This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 5 years ago.
I am new to C. I have stumbled upon certain behavior of feof I can't explain. Specifically in the code below I create a file, write one byte of information int it, then close and open it again, read the information (my 1 byte) till EOF is reached, then move the current position of the file pointer by 0 byte (i.e. do not change the current position at all) and suddenly I am not at the EOF any longer. How come?
#include <stdio.h>
#include <stdint.h>
typedef uint8_t BYTE;
int main(void) {
FILE* f = fopen("myfile.txt","w");
BYTE b = 0x0000;
fwrite(&b,1,1,f);
fclose(f);
f = fopen("myfile.txt","r");
while (!feof(f)){
fread(&b,1,1,f);
}
printf("We have reached EOF: %i \n",feof(f));
fseek(f,0,SEEK_CUR);
printf("We have reached EOF: %i \n",feof(f));
}
Output
We have reached EOF: 1
We have reached EOF: 0
From the fseek docs:
The end-of-file internal indicator of the stream is cleared after a successful call to this function, and all effects from previous calls to ungetc on this stream are dropped.
I just read in a string using the following statement:
fgets(string, 100, file);
This string that was just read in was the last line. If I call feof() now will it return TRUE? Is it the same as calling feof() right at the start before reading in any lines?
No, don't use feof() to detect the end of the file. Instead check for a read failure, for example fgets() will return NULL if it attempts to read past the end of the file whereas feof() will return 0 until some function attempts to read past the end of the file, only after that it returns non-zero.
Does feof() work when called after reading in last line?
No.
feof() becomes true when reading past the end of data. Reading the last line may not be pass the end of data if the last line ended in '\n'.
The short answer is NO. Here is why:
If fgets successfully read the '\n' at the end of the line, the end-of-file indicator in the FILE structure has not been set. Hence feof() will return 0, just like it should before reading anything, even on an empty file.
feof() can only be used to distinguish between end-of-file and read-error conditions after an input operation failed. Similarly, ferr() can be used to check for read-error after an input operation failed.
Programmers usually ignore the difference between end-of-file and read-error. Hence they only rely on checking if the input operation succeeded or failed. Thus they never use feof(), and so should you.
The behavior is somewhat similar as that of errno: errno is set by some library functions in case of error or failure. It is not reset to 0 upon success. Checking errno after a function call is only meaningful if the operation failed and if errno was cleared to 0 before the function call.
If you want to check if you indeed reached to the of file, you need to try and read extra input. For example you can use this function:
int is_at_end_of_file(FILE *f) {
int c = getc(file);
if (c == EOF) {
return 1;
} else {
ungetc(c, file);
return 0;
}
}
But reading extra input might not be worthwhile if reading from the console: it will require for the user to type extra input that will be kept in the input stream. If reading from a pipe or a device, the side effect might be even more problematic. Alas, there is no portable way to test if a FILE stream is associated with an actual file.
This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 8 years ago.
My question is about this fread() function that seems to be confusing for the time being. I create a binary file and put inside of it the values 1,2 and 3. And then I try to read the file and when I do using fread() it shows it like 1233 not 123.
#include <stdio.h>
#include <stdlib.h>
main ()
{
int x=1,y=2,z=3,i,j;
FILE *f;
f=fopen("Werid.bin","wb");
fwrite(&x,sizeof(int),1,f);
fwrite(&y,sizeof(int),1,f);
fwrite(&z,sizeof(int),1,f);
fclose(f);
f=fopen("Werid.bin","rb");
if (!f) perror("X");
while(!feof(f))
{
fread(&j,sizeof(int),1,f);
printf("%d",j);
}
fclose(f);
}
Why?
Change this
while(!feof(f))
to
while(fread(&j,sizeof(int),1,f) == 1)
From linux feof() manual
The function feof() tests the end-of-file indicator for the stream pointed to by stream, returning nonzero if it is set. The end-of-file indicator can only be
cleared by the function clearerr().
The feof() will return true after you try to call fread() at the end of file i.e. after you read the last number, you will need to call fread() again to set the end-of-file indicator.
So the loop will be executed one more time after the last read, and since it does not read anything but rather returns an error, it does not change the value of j either, so the previous value 3 is printed again.