Skip to content

Commit 1cbc11c

Browse files
committed
Exercise 7-06
1 parent ae2a07a commit 1cbc11c

File tree

5 files changed

+119
-3
lines changed

5 files changed

+119
-3
lines changed

INDEX.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,20 +98,23 @@ void daclear(void);
9898
[4] rpncalc4-06/dastack.c
9999
[4] rpncalc4-10/dastack.c
100100
[4] rpncalc4-11/dastack.c
101+
[7] scancalc/dastack.c
101102

102103
void dadup(void);
103104
[4] rpncalc4-04/dastack.c
104105
[4] rpncalc4-05/dastack.c
105106
[4] rpncalc4-06/dastack.c
106107
[4] rpncalc4-10/dastack.c
107108
[4] rpncalc4-11/dastack.c
109+
[7] scancalc/dastack.c
108110

109111
void dalist(void);
110112
[4] rpncalc4-04/dastack.c
111113
[4] rpncalc4-05/dastack.c
112114
[4] rpncalc4-06/dastack.c
113115
[4] rpncalc4-10/dastack.c
114116
[4] rpncalc4-11/dastack.c
117+
[7] scancalc/dastack.c
115118

116119
double dapeek(void);
117120
[4] rpncalc4-04/dastack.c
@@ -120,6 +123,7 @@ double dapeek(void);
120123
[4] rpncalc4-10/dastack.c
121124
[4] rpncalc4-11/dastack.c
122125
[5] expr/dastack.c
126+
[7] scancalc/dastack.c
123127

124128
double dapop(void)
125129
[4] rpncalc4-03/dastack.c
@@ -129,6 +133,7 @@ double dapop(void)
129133
[4] rpncalc4-10/dastack.c
130134
[4] rpncalc4-11/dastack.c
131135
[5] expr/dastack.c
136+
[7] scancalc/dastack.c
132137
[-] rpncalc/dastack.c
133138

134139
void dapush(double val);
@@ -139,6 +144,7 @@ void dapush(double val);
139144
[4] rpncalc4-10/dastack.c
140145
[4] rpncalc4-11/dastack.c
141146
[5] expr/dastack.c
147+
[7] scancalc/dastack.c
142148
[-] rpncalc/dastack.c
143149

144150
size_t dasize(void);
@@ -147,13 +153,15 @@ size_t dasize(void);
147153
[4] rpncalc4-06/dastack.c
148154
[4] rpncalc4-10/dastack.c
149155
[4] rpncalc4-11/dastack.c
156+
[7] scancalc/dastack.c
150157

151158
void daswap(void);
152159
[4] rpncalc4-04/dastack.c
153160
[4] rpncalc4-05/dastack.c
154161
[4] rpncalc4-06/dastack.c
155162
[4] rpncalc4-10/dastack.c
156163
[4] rpncalc4-11/dastack.c
164+
[7] scancalc/dastack.c
157165

158166
int day_of_year(int year, int month, int day);
159167
[5] datetools.c
@@ -207,6 +215,9 @@ void expand(char *source, char *target);
207215
size_t expandtab(size_t pos);
208216
[1] fold.c
209217

218+
void filecomp(FILE *fp1, FILE *fp2)
219+
[7] mindiff.c
220+
210221
size_t findblank(size_t pos);
211222
[1] fold.c
212223

@@ -275,6 +286,7 @@ size_t getline(char *s, size_t lim);
275286
[5] sort3.c
276287
[5] sort4.c
277288
[5] tail2.c
289+
[7] scancalc/lexer.c
278290

279291
char getop(char s[]);
280292
[4] rpncalc4-03/lexer.c
@@ -286,6 +298,9 @@ char getop(char s[]);
286298
[5] expr/lexer.c
287299
[-] rpncalc/lexer.c
288300

301+
char getop(char s[], double *val)
302+
[7] scancalc/lexer.c
303+
289304
int gettoken(void);
290305
[5] dcl.c
291306
[5] dcl2.c
@@ -382,6 +397,7 @@ void mathfun(char s[]);
382397
[4] rpncacl4-06/rpncalc4.c
383398
[4] rpncacl4-10/rpncalc5.c
384399
[4] rpncacl4-11/rpncalc6.c
400+
[7] scancalc/scancalc.c
385401

386402
#define max(a, b)
387403
[-] points.c

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ Kernighan and Ritchie The C Programming Language Code Examples
136136
* 7-03 - minprintf.c A minimal faux implementation of printf to demonstrate variable arguments
137137
* 7-04 - minscanf.c A minimal faux implementation of scanf to introduce scanf
138138
* 7-05 - scancalc/*.c A variation of whole line RPN calc from 4-10 that utilizes sscanf
139+
* 7-06 - mindiff.c A minimal file comparision utility - prints first line where two files differ
139140

140141
##Extras
141142

@@ -159,7 +160,8 @@ The following test data files are provided to support manually testing the exerc
159160
* bigline.txt - One really big single line of text (3001 chars)
160161
* bignegative.txt - A big (out of range) negative integer
161162
* comment.txt - A C program containing test scenarios for 'nocomment.c' and 'getword.c'
162-
* dcl.txt - Tst file for 'dcl.c'
163+
* dcl.txt - Test file for 'dcl.c'
164+
* dcl2.txt - Differs from 'dcl.c' slightly. Good test file for 'mincomp.c'
163165
* empty.txt - One empty line (just a '\n')
164166
* extraspecials.txt - Contains embedded backspace, tabs, and backslashes
165167
* huckfinn.txt - Project Gutenberg copy of Adventures of Huckleberry Finn by Mark Twain

data/dcl2.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
char **argv
2+
int (*daytab)[13]
3+
int *daytab[13]
4+
void *comp()
5+
void (*comp)()
6+
char (*(*x())[])()
7+
char (*(*x[])())[6]
8+
int (*daytab[13]
9+
char **
10+
void ( * comp)()
11+
hello

src/chapter07/Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ CFLAGS = -std=c99 -Wall -g -I.
66
LINT = splint
77
LINTFLAGS = -compdef +quiet +skip-sys-headers +charintliteral +charint -shadow -preproc -mustfreeonly -temptrans -nullret -nullpass -nullstate
88
DEPS =
9-
_OBJ = chngcase.o minprintf.o minscanf.o print.o
10-
_BIN = chngcase minprintf minscanf print
9+
_OBJ = chngcase.o mindiff.o minprintf.o minscanf.o print.o
10+
_BIN = chngcase mindiff minprintf minscanf print
1111

1212
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
1313

@@ -37,6 +37,10 @@ chngcase: $(ODIR)/chngcase.o
3737
cp -v $@ $(BIN)/upper
3838
cp -v $@ $(BIN)/lower
3939

40+
mindiff: $(ODIR)/mindiff.o
41+
$(CC) $(CFLAGS) $^ -o $@
42+
cp -v $@ $(BIN)/$@
43+
4044
minprintf: $(ODIR)/minprintf.o
4145
$(CC) $(CFLAGS) $^ -o $@
4246
cp -v $@ $(BIN)/$@

src/chapter07/mindiff.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* mindiff - Compares two files printing the first line where they differ
3+
*/
4+
5+
#include <stdio.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
9+
// Constants
10+
11+
#define MAXLINE 10000
12+
13+
/*
14+
* filecomp(): Compare two files
15+
*/
16+
17+
static void filecomp(FILE *fp1, FILE *fp2) {
18+
19+
char line1[MAXLINE];
20+
char line2[MAXLINE];
21+
char *lp1;
22+
char *lp2;
23+
24+
// Walk through both files comparing each line by line looking for
25+
// where they do not match
26+
27+
do {
28+
29+
// Get a line from each file (read a line into the line buffer for each file)
30+
lp1 = fgets(line1, MAXLINE, fp1);
31+
lp2 = fgets(line2, MAXLINE, fp2);
32+
33+
// If we were able to read a line from both files, then compare the lines. If
34+
// they are equal then proceed onward to the next line
35+
if (lp1 == line1 && lp2 == line2) {
36+
if (strcmp(line1, line2) != 0) {
37+
printf("First difference is:\n\n%s\n", line1);
38+
lp1 = NULL;
39+
lp2 = NULL;
40+
}
41+
42+
// Otherwise, we're at the end of one of the two files so we will print the last
43+
// line of the file we ended with
44+
} else if (lp1 != line1 && lp2 == line2)
45+
printf("End of first file reached at the following line:\n\n%s\n", line2);
46+
else
47+
printf("End of second file reached at the following line:\n\n%s\n", line2);
48+
} while (lp1 == line1 && lp2 == line2);
49+
50+
}
51+
52+
// Main
53+
54+
int main(int argc, char *argv[]) {
55+
56+
FILE *fp1;
57+
FILE *fp2;
58+
59+
// File names must be provided
60+
if (argc != 3) {
61+
fprintf(stderr, "mindiff: usage: mindiff <file1> <file2>\n");
62+
exit(EXIT_FAILURE);
63+
}
64+
65+
// Attempt to open the first file
66+
if ((fp1 = fopen(*++argv, "r")) == NULL) {
67+
fprintf(stderr, "mindiff: cannot open file %s\n", *argv);
68+
exit(EXIT_FAILURE);
69+
}
70+
71+
// Attempt to open the second file
72+
if ((fp2 = fopen(*++argv, "r")) == NULL) {
73+
fprintf(stderr, "mindiff: cannot open file %s\n", *argv);
74+
exit(EXIT_FAILURE);
75+
}
76+
77+
// Compare the two files
78+
filecomp(fp1, fp2);
79+
80+
// Close the files and exit (exit() closes files)
81+
82+
exit(EXIT_SUCCESS);
83+
}

0 commit comments

Comments
 (0)