K&R C Programs Exercise 7-6

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

Open both files, read them line by line in parallel, and compare. When a differing line is found, print both versions with a line number and exit. Also handle the case where one file is longer than the other.

Solution

/* K&R Exercise 7-6 — compare two files, print first differing line
 * Compile: gcc -ansi -Wall ex7-6.c -o ex7-6
 * Usage:   ./ex7-6 file1 file2 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXLINE 1000

int main(int argc, char *argv[])
{
    FILE *fp1, *fp2;
    char  line1[MAXLINE], line2[MAXLINE];
    int   lineno = 0;
    int   got1, got2;

    if (argc != 3) {
        fprintf(stderr, "Usage: %s file1 file2\n", argv[0]);
        return 1;
    }
    if ((fp1 = fopen(argv[1], "r")) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", argv[0], argv[1]);
        return 1;
    }
    if ((fp2 = fopen(argv[2], "r")) == NULL) {
        fprintf(stderr, "%s: can't open %s\n", argv[0], argv[2]);
        fclose(fp1);
        return 1;
    }

    for (;;) {
        got1 = (fgets(line1, MAXLINE, fp1) != NULL);
        got2 = (fgets(line2, MAXLINE, fp2) != NULL);
        lineno++;

        if (!got1 && !got2) {
            printf("files are identical\n");
            break;
        }
        if (!got1) {
            printf("line %d: %s is shorter (extra: %s)\n",
                   lineno, argv[1], argv[2]);
            break;
        }
        if (!got2) {
            printf("line %d: %s is shorter (extra: %s)\n",
                   lineno, argv[2], argv[1]);
            break;
        }
        if (strcmp(line1, line2) != 0) {
            printf("first difference at line %d:\n", lineno);
            printf("< %s", line1);
            printf("> %s", line2);
            /* add newlines if lines lack them (last line without \n) */
            if (line1[strlen(line1)-1] != '\n') putchar('\n');
            if (line2[strlen(line2)-1] != '\n') putchar('\n');
            break;
        }
    }

    fclose(fp1);
    fclose(fp2);
    return 0;
}

Compile and Test

gcc -ansi -Wall ex7-6.c -o ex7-6

printf "apple\nbanana\ncherry\n"  > /tmp/f1.txt
printf "apple\nblueberry\ncherry\n" > /tmp/f2.txt
./ex7-6 /tmp/f1.txt /tmp/f2.txt

Expected Output

first difference at line 2:
< banana
> blueberry

More Test Cases

# Identical files
cp /tmp/f1.txt /tmp/f3.txt
./ex7-6 /tmp/f1.txt /tmp/f3.txt    # "files are identical"

# One file is a prefix of the other
printf "apple\nbanana\n" > /tmp/f4.txt
./ex7-6 /tmp/f1.txt /tmp/f4.txt    # "file1 is shorter..."

What This Exercise Teaches

  • Parallel file reading — reading from two files simultaneously with a shared line counter is the foundation of diff-style tools; maintaining independent fgets calls per file keeps the loop clean
  • File-length asymmetry — both files hitting EOF together means identical; one hitting EOF first means that file is shorter; the got1/got2 flags make all three cases explicit
  • Trailing-newline edge case — the last line of a file may not end in \n; checking before printing the extra newline avoids a double blank line in the output

Set Up Your C Environment

← Exercise 7-5  | 
Chapter 7 Solutions  | 
Exercise 7-7 →

Book: The C Programming Language, 2nd Ed — Kernighan & Ritchie

1 comment on “K&R C Programs Exercise 7-6

  • Alana Spangenberg says:

    How do i best copyright protect stories and content on my writing internet site? I know you are able to insert a copyright sign, but may this TOTALLY protect against someone copying and pasting your stuff and declaring that it is their own?.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>