/* file14 is similar to file13, but can compare three or more files, to see whether all the files are the same. If there's a difference, it identifies two files that differ, and says how many bytes are the same before the first difference. file14 calls exitifdifferent(argv[1],argv[2]), then exitifdifferent(argv[2],argv[3]), etc., until exitifdifferent(argv[argc - 2],argv[argc - 1]). The exitifdifferent() function uses an fclose() for each fopen(), to free the resources allocated by fopen(). This makes the program usable for thousands of files. To see whether this works, try creating a file test14 that says #!/bin/sh ./file14 file14.c file14.c file14.c file14.c with file14.c repeated 1000 times rather than 4 times. (Don't type this manually! Write a separate program to create test14.) Type chmod 755 test14 to turn test14 into a shell script, and type ./test14 to run ./file14 file14.c file14.c etc. Then try removing one of the fclose() lines from file14.c; recompile file14.c and try ./test14 again. */ #include #include #include void die(char *operation,char *filename) { fprintf(stderr,"fatal: unable to %s %s: %s\n" ,operation,filename,strerror(errno)); exit(111); } FILE *safefopen(char *filename,char *how) { FILE *f = fopen(filename,how); if (!f) die("open",filename); return f; } int safefgetc(char *filename,FILE *f) { int result = fgetc(f); if (result != -1) return result; if (ferror(f)) die("read",filename); return -1; } void exitifdifferent(char *filename1,char *filename2) { FILE *f1 = safefopen(filename1,"r"); FILE *f2 = safefopen(filename2,"r"); int bytes = 0; int d1; int d2; do { d1 = safefgetc(filename1,f1); d2 = safefgetc(filename2,f2); if (d1 != d2) { printf("Files %s and %s differ after %d bytes.\n" ,filename1,filename2,bytes); exit(0); } ++bytes; } while (d1 != EOF); fclose(f1); fclose(f2); } 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); }