Write a program to compare two files, printing the first line where they differ.
Here's Rick's solution:
/******************************************************
KnR 7-6
--------
Write a program to compare two files and print the
first line where they differ.
Author: Rick Dearman
email: rick@ricken.demon.co.uk
Note: This program prints ALL the lines that are
different using the <> indicators used by
the unix diff command. However this program
will not cope with something as simple as a
line being removed.
In reality the program would be more useful
if it searched forward for matching lines.
This would be a better indicator of the simple
removal of some lines.
This has lead me to track down a version of the
"diff" command available on GNU/Linux systems.
for more information go to the web site at:
www.gnu.org
******************************************************/
#include <stdio.h> #include <string.h> #define MAXLINE 1000 void diff_line( char *lineone, char *linetwo, int linenumber ) { if(strcmp (lineone, linetwo) < 0 || strcmp (lineone, linetwo) > 0) printf( "%d<%s\n%d>%s\n", linenumber, lineone, linenumber, linetwo); } int main(int argc, char *argv[] ) { FILE *fp1, *fp2; char fp1_line[MAXLINE], fp2_line[MAXLINE]; int i; if ( argc != 3 ) { printf("differ fileone filetwo\n"); exit(0); } fp1 = fopen( argv[1], "r" ); if ( ! fp1 ) { printf("Error opening file %s\n", argv[1]); } fp2 = fopen( argv[2], "r" ); if ( ! fp2 ) { printf("Error opening file %s\n", argv[2]); } i = 0; while ( (fgets(fp1_line, MAXLINE, fp1) != NULL) && (fgets(fp2_line, MAXLINE, fp2) != NULL)) { diff_line( fp1_line, fp2_line, i ); i++; } return 0; }
and here's "flippant squirrel"'s solution:
/* Exercise 7-6 - write a program to compare two files, printing the first line
* where they differ
*
* Note : I amended this a bit...if a file is shorter than the other, but is identical
* up to that point, the program prints out "EOF" as the string that's not equal.
*
*/
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFF_SIZE 1000 /* uses fgets, removes the '\n' at the end of the string if it exists */ char *safegets(char *buffer, int length, FILE *file) { char *ptr; int len; if (buffer != NULL) { ptr = fgets(buffer, length, file); if (ptr != NULL) { len = strlen(buffer); if (len > 0) { if (buffer[len - 1] == '\n') { buffer[len - 1] = '\0'; } } } return ptr; } return NULL; } int main(int argc, char *argv[]) { FILE *leftFile, *rightFile; char buff1[BUFF_SIZE], buff2[BUFF_SIZE]; char *ptr1, *ptr2; unsigned long lineNum = 0; if (argc < 3) { fprintf(stderr, "Usage : 7_6 <path to file> <path to file>\n"); return 0; } if (!(leftFile = fopen(argv[1], "r"))) { fprintf(stderr, "Couldn't open %s for reading\n", argv[1]); return 0; } if (!(rightFile = fopen(argv[2], "r"))) { fprintf(stderr, "Couldn't open %s for reading\n", argv[2]); fclose(leftFile); /* RJH 10 Jul 2000 */ return 0; } /* read through each file, line by line */ ptr1 = safegets(buff1, BUFF_SIZE, leftFile); ptr2 = safegets(buff2, BUFF_SIZE, rightFile); ++lineNum; /* stop when either we've exhausted either file's data */ while (ptr1 != NULL && ptr2 != NULL) { /* compare the two lines */ if (strcmp(buff1, buff2) != 0) { printf("Difference:\n"); printf("%lu\t\"%s\" != \"%s\"\n", lineNum, buff1, buff2); goto CleanUp; } ptr1 = safegets(buff1, BUFF_SIZE, leftFile); ptr2 = safegets(buff2, BUFF_SIZE, rightFile); ++lineNum; } /* * if one of the files ended prematurely, it definitely * isn't equivalent to the other */ if (ptr1 != NULL && ptr2 == NULL) { printf("Difference:\n"); printf("%lu\t\"%s\" != \"EOF\"\n", lineNum, buff1); } else if (ptr1 == NULL && ptr2 != NULL) { printf("Difference:\n"); printf("%lu\t\"EOF\" != \"%s\"\n", lineNum, buff2); } else { printf("No differences\n"); } CleanUp: fclose(leftFile); fclose(rightFile); return EXIT_SUCCESS; }