Ftell for text files

497 views Asked by At

I use this little program to understand how ftell works. I created a txt file and i typed in "15" and below that, in a second line, "no". So what I expected was it to print 0, then after it reads 15, print 2 and then since no is on the second line, meaning I have left a few "available spots" on the first line which i could have filled with more characters i would expect it to print definitely bigger number than 7 (which is what it actually printed). WHY?

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *fp;
    int x;
    char box[10];

    fp = fopen("test.txt", "r");

    printf("%ld", ftell(fp));

    fscanf(fp,"%d",&x );
    printf("\n%ld", ftell(fp));

    fscanf(fp, "%s", box);
    printf("\n%ld\n", ftell(fp));
}

output: 0 2 7

2

There are 2 answers

6
Serge Ballesta On

There are nothing like available slots in a text file(*). It is just a mere sequence of characters, some of then being interpreted as an End Of Line (commonly \r, \n or \r\n). So your text file should contain the following characters (assuming DOS/Windows EOL):

1 5 \r \n n o \r \n

This one should give for output: 0 2 6.

If you have 7 as the last value, you have probably a space somewhere, probably at the end of the first line (between 5 and \r).


At least on common OS, text files are represented as streams with line delimiters. Thanks to @JohnBollinger for noticing that other OS could have featured fixed lenght records text files

1
Ctx On

Assuming, that your file contains:

"15\r\nno\r\n"

Then the first conversion reads in 1 (pos. 1) and 5 (pos. 2), then reads the carriage return \r (pos. 3), which it ungetc()s (pos. 2 again).

Then, the next string is read in (no) and the \r is hit, which is again pushed back into the stream, hence the position should be 6. To explain the 7, there has to be some extra blank between the 15 and the no (trailing or leading space for example).

So, speaking generally, the position is always the last char, that *scanf() converted. The next (non-matching) char has to be read in, but is pushed back into the stream.