Reading from a binary file using fread() displays additional characters [duplicate] - c

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.

Related

Why extra 'ÿ' added when writing into a .txt file in C? [duplicate]

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.

C: strange behavior of feof [duplicate]

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.

Why can't I access EOF using fseek()? [duplicate]

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.

fgetc reads character with value = -1

fgetc() function reads characters from a text file in Ubuntu.
the last character before EoF is with code = -1.
what the heck is that?
in text editor file seems ok, no strange symbols at end.
while (!feof(fp))
{
c = fgetc(fp);
printf("%c %i\n", c, c);//
}
feof is meant to signal that you've tried to read past the end of file - which means that you first have to reach it. So it will only work after you try to read and the system realizes you're at the end. And what does fgetc return if you try to read past the end of file? EOF (conveniently, -1 - which is why fgetc returns an int instead of a char).
So what's happening is that you enter the loop - because you haven't yet tried to read past at the end yet - and call fgetc which returns -1 because you tried to read past the end of the file. The next time around the loop, feof tells you that you've already hit the end of the file and tried to read past it and you break out.
You should read the documentation of functions you intend to use: feof and fgetc documentation explain this. But even if they did not, a simple google search would have answered your question: Why is “while ( !feof (file) )” always wrong?.

Repetition of final line when computing sum? [duplicate]

This question already has answers here:
Why is “while( !feof(file) )” always wrong?
(5 answers)
Closed 9 years ago.
I'm taking my first programming class ever this year and I'm slight confused on this. I'm trying to learn the fopen and fclose functions currently.
My code is
int main(void)
{
FILE *input; /* Pointer to the input file */
double values;
double sum;
input = fopen("data.dat", "r"); /* Prepare file for input */
sum = 0;
while (!feof(input))
{ fscanf(input, "%lf", &values);
sum = sum + values;
}
printf("The sum of the values is %f\n", sum);
fclose(input);
return 0;
}
When I compile this to get the sum, the last value of the data.dat file is counted for twice.
I was wondering how I could fix this.
Thanks!
You should not use while(!feof(...)) because it's always wrong. Why?
It will, as you found out, loop one more time than you expect. That happens because the semantics of feof() are not what you think: that is, they are not to check if the next read will reach the end of file. Instead, feof allows you distinguish between a read error and the end of the file after you get a zero from a read (or some other similar call).
The solution to your problem is easy: use the functions you call properly. fscanf returns a value - you should find out what that value is and, more importantly, what it means.

Resources