/* file16 has the same effect as file15. The only difference is that comparefile() has been split into three functions, in a way that makes it obvious that there's exactly one fclose() for each successful fopen(). It's a good idea to use this style for any function that allocates temporary resources. Thought experiment: What will this program (and file14 and file15) do if two files are different, but the first difference is after exactly 2147483648 bytes? Or 4294967297 bytes? Or 4294967295 bytes? Or 4294967296 bytes? Hint: Remember dyn1.c and dyn2.c. Can you fix this problem? You should be able to make sure that your fix doesn't change the output of this program for small files, even though you don't have any 4-gigabyte files to test. (This problem couldn't occur for disk files in the old days, when we had to walk fifty miles uphill to and from school through the snow in the middle of the summer. My first 300-megabyte disk had a volume label of F***INGHUGE. 4-gigabyte disks were unthinkably large. Today's 100-gigabyte disks are truly wonderful. Can you figure out why the Computer Center still has tight quotas?) */ #include #include #include int comparefile12(char *filename1,FILE *f1,char *filename2,FILE *f2) { int bytes = 1; int d1; int d2; do { d1 = fgetc(f1); if (d1 == -1) if (ferror(f1)) return -3; d2 = fgetc(f2); if (d2 == -1) if (ferror(f2)) return -4; if (d1 != d2) return bytes; ++bytes; } while (d1 != EOF); return 0; } int comparefile1(char *filename1,FILE *f1,char *filename2) { FILE *f2 = fopen(filename2,"r"); int result; if (!f2) return -2; result = comparefile12(filename1,f1,filename2,f2); fclose(f2); return result; } int comparefile(char *filename1,char *filename2) { FILE *f1 = fopen(filename1,"r"); int result; if (!f1) return -1; result = comparefile1(filename1,f1,filename2); fclose(f1); return result; } void die(char *operation,char *filename) { fprintf(stderr,"fatal: unable to %s %s: %s\n" ,operation,filename,strerror(errno)); exit(111); } void exitifdifferent(char *filename1,char *filename2) { int result = comparefile(filename1,filename2); switch(result) { case 0: return; case -1: die("open",filename1); case -2: die("open",filename2); case -3: die("read",filename1); case -4: die("read",filename2); } printf("Files %s and %s differ after %d bytes.\n" ,filename1,filename2,result - 1); exit(0); } int main(int argc,char **argv) { if (*argv) ++argv; while (argv[0] && argv[1]) { exitifdifferent(argv[0],argv[1]); ++argv; } printf("All the files are the same.\n"); exit(0); }