/* file13 has the same effect as file10, file11, and file12. It uses fgetc() instead of fscanf(). d1 in file13.c, the result of getchar(), fgetc(), safefgetc(), etc., is a combination of c1 and havec1 in file12.c: havec1 c1 d1 situation 0 ? -1 end of file (or error, eliminated by safefgetc) 1 0 0 the byte we just read was a 0 1 1 1 the byte we just read was a 1 1 2 2 the byte we just read was a 2 ... 1 65 65 the byte we just read was a 65 ('A') 1 66 66 the byte we just read was a 66 ('B') ... 1 255 255 the byte we just read was a 255 Note that d1 is an int, not a char; a char does not have enough room for -1, 0, 1, ..., 255. Note also that safefgetc() is returning only one value, so it doesn't need call-by-reference as safegetbyte() did, although it still uses pointers for filename and f. Can you rewrite safefgetc() to use fscanf(), and rewrite safegetbyte() to use fgetc()? */ #include #include #include void die(char *operation,char *filename) { fprintf(stderr,"fatal: unable to %s %s: %s\n" ,operation,filename,strerror(errno)); exit(111); } void exit_same(void) { printf("The files have the same contents.\n"); exit(0); } void exit_different(void) { printf("The files have different contents.\n"); exit(0); } 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; } int main(int argc,char **argv) { FILE *f1; FILE *f2; int d1; int d2; if (argc < 3) { fprintf(stderr,"usage: file13 f1 f2\n"); exit(100); } f1 = safefopen(argv[1],"r"); f2 = safefopen(argv[2],"r"); for (;;) { d1 = safefgetc(argv[1],f1); d2 = safefgetc(argv[2],f2); if (d1 != d2) exit_different(); if (d1 == EOF) exit_same(); } }