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;
}
source to share
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;
}
source to share
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.
source to share