|
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