"The C Programming Language", 2nd edition, Kernighan and Ritchie

Answer to Exercise 7-6, page 165

Solutions by Rick Dearman and "Flippant Squirrel" .



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;    
}


Back to index





You are visitor number - call again soon!