cftell

Use ftell to find the file size


  fseek(f, 0, SEEK_END); 
  size = ftell(f);

If ftell(f) tells us the current file position, the size here should be the offset from the end of the file to the beginning. Why is the size not ftell(f)+1? Should not ftell(f) only give us the position of the end of the file?


Solution

  • File positions are like the cursor in a text entry widget: they are in between the bytes of the file. This is maybe easiest to understand if I draw a picture:

    Depiction of a file that is four characters long. There are five boxes in a row; from left to right, they contain the letters "a", "b", "c", and "d", and the fifth one has its area X-ed out.  Below the boxes, aligned with the vertical lines to the left of and in between the boxes, are the numbers 0, 1, 2, 3, and 4.

    This is a hypothetical file. It contains four characters: a, b, c, and d. Each character gets a little box to itself, which we call a "byte". (This file is ASCII.) The fifth box has been crossed out because it's not part of the file yet, but but if you appended a fifth character to the file it would spring into existence.

    The valid file positions in this file are 0, 1, 2, 3, and 4. There are five of them, not four; they correspond to the vertical lines before, after, and in between the boxes. When you open the file (assuming you don't use "a"), you start out on position 0, the line before the first byte in the file. When you seek to the end, you arrive at position 4, the line after the last byte in the file. Because we start counting from zero, this is also the number of bytes in the file. (This is one of the several reasons why we start counting from zero, rather than one.)

    I am obliged to warn you that there are several reasons why

    fseek(fp, 0, SEEK_END);
    long int nbytes = ftell(fp);
    

    might not give you the number you actually want, depending on what you mean by "file size" and on the contents of the file. In no particular order: