Obfuscated but interesting behavior of C when calculating file size

I am writing a very simple C program to calculate the size of a file. I have success counting both text and binary files. However, after making some minor changes to the code, I get different output for .odt and binaries.

This is my code that gives the correct results:

while(fgetc(pFile)!=EOF) size++;

      

And this is the one giving me different and wrong results for binaries and odt files (and I can't figure out why it's different?)

   size=0; 

   c=fgetc(pFile);

   while(c!=EOF)
   {

      c=fgetc(pFile); 
      size++;
   }

      

Note. This code gives correct results for text files.

This is the generic code (function):

 int count(char * file)
 {
     int size;
     char c;
     FILE * pFile;

     size=0;
     c=' ';

     pFile = fopen(file, "rb");
     if(!pFile)
     {
        printf("Invalid file(%s)!\n",file); 
        exit(EXIT_SUCCESS);
     }

     c=fgetc(pFile);
     while(c!=EOF)
     {
        c=fgetc(pFile); 
        size++;
     }
     // while(fgetc(pFile)!=EOF) size++;

     fclose(pFile);

     return size;
}

      

+3


source to share


3 answers


I'm sure it was an announcement c

. Here's some sample code that works.



#include <stdio.h>
#include <errno.h>

int fsize(char *s)
{
    FILE *pF = NULL;
    int c = 0;  /* declaring this as char will bring you funny results */
    int iSize = 0;

    pF = fopen(s, "r");
    if (! pF)
    {
        perror("Cannot open file");
        return -1;
    }

    fseek(pF, 0, SEEK_SET);

    while(EOF != (c = fgetc(pF)))
        iSize ++;

    fclose(pF);

    return iSize;
}

int main(int argc, char **argv)
{
    int i;

    for(i = 1; argc > i; i ++)
        printf("%10d  %s\n", fsize(argv[i]), argv[i]);

    return 0;
}

      

+1


source


I'm not sure what you mean by "calculating file size". But if you want the file size,

I hope the following code looks like.



#include <sys/stat.h>

struct stat sbuf;

stat(filepath, &sbuf);

printf("%jd\n", (intmax_t)sbuf.st_size);

      

-2


source


I believe the file size is slightly smaller than the actual size.
The reason I believe it is c=fgetc(pFile);

is recorded twice. One outside and one inside. The control executes first c=fgetc(pFile);

, navigates in time, and then internally again, executing c=fgetc(pFile);

without increasing size.

   size=0; 
   c=fgetc(pFile);
   if(c!=EOF)
   {
     size++;
   }
   while(c!=EOF)
   {

      c=fgetc(pFile); 
      size++;
   }

      

Here, if the file is empty, fgetc will return EOF. Thus, we only increase the number if c is returned with a value other than EOF. This should fix it. Hope this helped.

-2


source







All Articles