|
5 | 5 | * By Faisal Saadatmand
|
6 | 6 | */
|
7 | 7 |
|
8 |
| -#define MAXFILES 3 |
9 |
| -#define MAXLEN 1000 |
| 8 | +#define MAXLEN 1000 /* maximum line length */ |
| 9 | +#define MAXNAME 100 /* maximum length of file name */ |
10 | 10 |
|
11 | 11 | #include <stdio.h>
|
12 | 12 | #include <stdlib.h>
|
13 | 13 | #include <string.h>
|
14 | 14 |
|
15 |
| -int main(int argc, char *argv[]) |
| 15 | +/* types */ |
| 16 | +typedef struct { |
| 17 | + char name[MAXNAME]; /* file name */ |
| 18 | + FILE *fptr; /* file pointer */ |
| 19 | + char line[MAXLEN]; /* currently read line */ |
| 20 | + int lineno; /* number of read lines */ |
| 21 | +} File; |
| 22 | + |
| 23 | +/* globals */ |
| 24 | +char *prog; /* program name */ |
| 25 | + |
| 26 | +/* functions */ |
| 27 | +void openfile(const char *, File *); |
| 28 | +void comparefiles(File *, File *); |
| 29 | + |
| 30 | +void openfile(const char *filename, File *file) |
16 | 31 | {
|
17 |
| - FILE *file[MAXFILES]; /* array to store files */ |
18 |
| - char *prog = argv[0]; /* program name for errors */ |
19 |
| - char *f1name = argv[1]; /* file 1 name for printing line */ |
20 |
| - char *f2name = argv[2]; /* file 2 name for printing line */ |
21 |
| - char f1line[MAXLEN], f2line[MAXLEN]; /* currently read line */ |
22 |
| - int f1lnum, f2lnum; /* currently read line number */ |
23 |
| - int i; |
24 |
| - |
25 |
| - /* check cli argument */ |
26 |
| - if (argc != 3) { |
27 |
| - fprintf(stderr, "Usage: %s <file1> <file2>\n", prog); |
| 32 | + if (!(file->fptr = fopen(filename, "r"))) { |
| 33 | + fprintf(stderr, "%s: ca't open %s\n", prog, filename); |
28 | 34 | exit(EXIT_FAILURE);
|
29 | 35 | }
|
| 36 | + strcpy(file->name, filename); |
| 37 | + file->lineno = 0; |
| 38 | +} |
30 | 39 |
|
31 |
| - /* open files */ |
32 |
| - for (i = 1; --argc > 0; ++i) /* skip file[0] for readability */ |
33 |
| - if (!(file[i] = fopen(*++argv, "r"))) { |
34 |
| - fprintf(stderr, "%s: can't open %s\n", prog, *argv); |
35 |
| - exit(EXIT_FAILURE); |
36 |
| - } |
37 |
| - |
38 |
| - f1lnum = f2lnum = 0; |
39 |
| - while (!feof(file[1]) && !feof(file[2])) { |
40 |
| - /* read lines and count successfully read lines */ |
41 |
| - if (fgets(f1line, MAXLEN, file[1])) |
42 |
| - f1lnum++; |
43 |
| - if (fgets(f2line, MAXLEN, file[2])) |
44 |
| - f2lnum++; |
45 |
| - /* compare lines */ |
46 |
| - if (f1lnum > f2lnum) /* file 1 is longer */ |
47 |
| - fprintf(stdout, "\n%s: %i: %s", f1name, f1lnum, f1line); |
48 |
| - else if (f1lnum < f2lnum) /* file 2 is longer */ |
49 |
| - fprintf(stdout, "\n%s: %i: %s", f2name, f2lnum, f2line); |
50 |
| - else if (strcmp(f1line, f2line)) { |
51 |
| - fprintf(stdout, "\n%s: %i: %s\n", f1name, f1lnum, f1line); |
52 |
| - fprintf(stdout, "\n%s: %i: %s\n", f2name, f2lnum, f2line); |
53 |
| - break; /* break at first difference */ |
54 |
| - } |
55 |
| - } |
| 40 | +void comparefiles(File *f1, File *f2) |
| 41 | +{ |
| 42 | + do { |
| 43 | + if (fgets(f1->line, MAXLEN, f1->fptr)) |
| 44 | + ++f1->lineno; |
| 45 | + if (fgets(f2->line, MAXLEN, f2->fptr)) |
| 46 | + ++f2->lineno; |
| 47 | + if (!feof(f1->fptr) && !feof(f2->fptr)) /* are there lines? */ |
| 48 | + if (strcmp(f1->line, f2->line)) /* compare lines */ |
| 49 | + break; /* lines differ */ |
| 50 | + } while (!feof(f1->fptr) && !feof(f2->fptr)); /* until either return EOF */ |
| 51 | + if (!feof(f1->fptr)) |
| 52 | + fprintf(stdout, "\n%s:%i: %s", f1->name, f1->lineno, f1->line); |
| 53 | + if (!feof(f2->fptr)) |
| 54 | + fprintf(stdout, "\n%s:%i: %s", f2->name, f2->lineno, f2->line); |
| 55 | +} |
56 | 56 |
|
57 |
| - fclose(file[1]); |
58 |
| - fclose(file[2]); |
| 57 | +int main(int argc, char *argv[]) |
| 58 | +{ |
| 59 | + File file_1, file_2; |
59 | 60 |
|
| 61 | + prog = *argv++; /* program name for errors */ |
| 62 | + if (--argc != 2) { /* check cli argument */ |
| 63 | + fprintf(stderr, "Usage: %s <file1> <file2>\n", prog); |
| 64 | + exit(EXIT_FAILURE); |
| 65 | + } |
| 66 | + openfile(*argv++, &file_1); |
| 67 | + openfile(*argv, &file_2); |
| 68 | + comparefiles(&file_1, &file_2); |
| 69 | + fclose(file_1.fptr); |
| 70 | + fclose(file_2.fptr); |
60 | 71 | exit(EXIT_SUCCESS);
|
61 | 72 | }
|
0 commit comments