'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 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.

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