The C Programming Language

Chapter 7 - Input and Output 6

mmresult 2017. 12. 22. 10:52

Write a program to compare two files, printing the first line where they differ.

Solutions by Rick Dearman and Flippant Squirrel .

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

 

 Category 1 Solution by Jose G. López

/* Compares two files, printing the first line where they differ.
   Note: Uses standard functions for managing files: fgetpos, fsetpos.
         With them we do not have limits about the length of a line.
         Only shows the differences compared on the file1. */

#include <stdio.h>
#include <stdlib.h> /* exit() function */

FILE *open_file(char *s);
int differ_files(FILE *fp1, FILE *fp2);

int main(int argc, char *argv[])
{
 FILE *fp1, *fp2;

 if (argc != 3) {
  printf("Usage: [program] file1 file2\n");
  exit(1);
 } else {
  fp1 = open_file(*++argv);
  fp2 = open_file(*++argv);
  differ_files(fp1, fp2);
  fclose(fp1);
  fclose(fp2);
 }

 return 0;
}

FILE *open_file(char *s)
{
 FILE *fp;

 if ((fp = fopen(s, "r")) == NULL) {
  fprintf(stderr, "Can't open file %s\n", s);
  exit(2);
 }
 return fp;
}

int differ_files(FILE *fp1, FILE *fp2)
{
 int c, d;
 int lin, retc;
 fpos_t posc; /* to store or set the file position */

 retc = fgetpos(fp1, &posc);
 c = fgetc(fp1);
 d = fgetc(fp2);
 lin = 1;
 while (c == d && c != EOF && d != EOF) {
  if (c == '\n') {                /* at the beginning of a new line */
   retc = fgetpos(fp1, &posc); /* we save the file position */
   lin++;
  }
  c = fgetc(fp1);
  d = fgetc(fp2);
 }
 /* if there are differences and we can set the file position */
 if (c != d && !retc && !fsetpos(fp1, &posc)) {
  printf("Differences found!\nAt line %d - \"", lin);
  while ((c = fgetc(fp1)) != EOF && c != '\n')
    printf("%c", c);
  printf("\"\n");
 }
 return (c != d);
}

 

 

'The C Programming Language' 카테고리의 다른 글

Chapter 7 - Input and Output 8  (0) 2017.12.22
Chapter 7 - Input and Output 7  (0) 2017.12.22
Chapter 7 - Input and Output 5  (0) 2017.12.22
Chapter 7 - Input and Output 4  (0) 2017.12.22
Chapter 7 - Input and Output 3  (0) 2017.12.22