'is END OF FILE (EOF) right after the end of text or depends on the compiler?
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;
}
Solution 1:[1]
You need to flush the stream after writing and before reading:
7.21.5.3 The fopen functionC 2011 Online Draft
...
7 When a file is opened with update mode ('+' as the second or third character in the above list ofmode
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 thefflush
function or to a file positioning function (fseek
,fsetpos
, orrewind
), 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.
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.
Solution 2:[2]
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()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |