From 54b3475b3041bf35c25bfad2f521d5751e6eadbf Mon Sep 17 00:00:00 2001 From: zlg Date: Thu, 17 Nov 2016 07:34:18 -0800 Subject: Solve Exercise 7-6: simple `diff` utility --- ch7/7-06_simple-diff.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 ch7/7-06_simple-diff.c diff --git a/ch7/7-06_simple-diff.c b/ch7/7-06_simple-diff.c new file mode 100644 index 0000000..ba0c58f --- /dev/null +++ b/ch7/7-06_simple-diff.c @@ -0,0 +1,81 @@ +#include +#include +#include + +/* The C Programming Language: 2nd Edition + * + * Exercise 7-6: Write a program to compare two files, printing the first line + * where they differ. + * + * Notes: `cat` is a surprisingly small program, and that trend continues with + * this little `diff` rip-off. This could probably be done with sparing, + * careful use of 'goto', but that's generally in the realm of "you better know + * what you're doing". I feel that the code explains itself here. + */ + +#define LINE_MAX 200 + +int mygetline(char *line, int max); +int max(int x, int y); + +int main(int argc, char *argv[]) { + /* Setup the file pointers so we can iterate through them */ + FILE *fileA; + FILE *fileB; + char *prog = argv[0]; + char line1[LINE_MAX]; + char line2[LINE_MAX]; + int len1 = 0; + int len2 = 0; + int done = 0; + if (argc != 3) { + fprintf(stderr, "%s: you must compare two files.\n", prog); + exit(1); + } + /* Setup our file pointers */ + if ((fileA = fopen(argv[1], "r")) == NULL) { + fprintf(stderr, "%s: could not open file '%s'\n", prog, argv[1]); + exit(2); + } + if ((fileB = fopen(argv[2], "r")) == NULL) { + fprintf(stderr, "%s: could not open file '%s'\n", prog, argv[2]); + exit(2); + } + while (done == 0) { + len1 = fetchline(fileA, line1, LINE_MAX); + len2 = fetchline(fileB, line2, LINE_MAX); + if (len1 == 0 || len2 == 0) { + break; + } + /* If their length is different, then the lines themselves are + * different */ + if (len1 != len2) { + done = 1; + break; + } + /* Basic string comparison's all we need to determine if there's a + * match or not. */ + if (strcmp(line1, line2) != 0) { + done = 1; + break; + } + } + if (done != 0) { + printf("These lines do not match:\n"); + printf("%20s: %s%20s: %s", argv[1], line1, argv[2], line2); + return 0; + } +} + +int max(int x, int y) { + return (x > y) ? x : y; +} + +/* Stealing this from the book because it makes life simpler */ +int fetchline(FILE *fp, char *line, int max) { + if (fgets(line, max, fp) == NULL) { + return 0; + } else { + return strlen(line); + } +} -- cgit v1.2.3-54-g00ecf ss='left'>AgeCommit message (Expand)AuthorFilesLines 2018-10-06cli: change "Status" heading to "Progress"zlg2-36/+40 2018-09-29Bump to 0.3alpha5 for PyPIzlg1-1/+1 2018-09-29cli: Add pretty printing to 'list' commandzlg3-17/+107 2018-09-08setup.py: Bump to alpha4 for PyPIzlg1-1/+1 2018-09-08cli: add '--raw' option to list commandzlg2-9/+45 2018-09-08Add remaining filters to vgstash packagezlg1-2/+11 2018-09-04Update LICENSE to match setup.pyzlg1-80/+67 2018-09-03Branch off from master with pytest, tox, clickzlg16-778/+779 2018-03-18Flesh out filter types and ownership statuszlg3-82/+144 2018-03-18README.mdown: break line correctlyzlg1-1/+1 2018-03-18add 'playlog' list filterzlg2-2/+9 2018-03-13Update helpers a bitzlg1-2/+9 2018-03-13Make VGSTASH_DB_LOCATION point to a filezlg2-21/+20 2016-11-18Remove settings from helpers.shZe Libertine Gamer1-5/+0 2016-11-15Correct phrasing in README.Ze Libertine Gamer1-4/+4 2016-11-13DerpZe Libertine Gamer1-0/+1 2016-11-03Improve error handling in shell scriptsZe Libertine Gamer4-3/+23 2016-10-24Correct run_again, add recursionZe Libertine Gamer1-0/+4 2016-10-21Add quotes to correct behavior for arglistZe Libertine Gamer1-1/+1 2016-10-14updater.sh: add recursion, error handlingZe Libertine Gamer1-43/+101 2016-10-14Correct pipe-handling behaviorZe Libertine Gamer1-1/+9 2016-10-12Clarify a method to move between platformsZe Libertine Gamer1-2/+5