NivaarExam PrepOfficial exam papers ↗

25-Comp-A4 Program Design and Data Structures · December 2017

Question 4 of 9: File I/O — Whitespace-Insensitive File Comparison

Nivaar worked solution (AI-drafted; not reviewed by a licensed engineer)

Notes on this paper

Paper format. 98-Comp-A4 Program Design and Data Structures, December 2017 — 3 hours, closed book, no calculator permitted. Nine questions of equal weight (20 marks each: 1 and 7 split as (a) 10 + (b) 10, 8 split as (a) 15 + (b) 5); candidates answer any six, so a complete paper is 120 marks. Pseudocode or any high-level language is accepted, and the examiner's note states explicitly that marking emphasises the operation of the program, not syntactic details. All nine questions are answered below, because the whole set is the more useful revision resource. Answers are given in C or C++ as the question dictates; each is compilable as written (or corrected where the printed paper itself has a slip), but a clear, correctly reasoned pseudocode answer would earn the same marks.

Reference texts for this subject.

  • Cormen, Leiserson, Rivest & Stein, Introduction to Algorithms, 4th ed. — tree traversals and BSTs (ch. 12), recursion and divide-and-conquer (ch. 2, 4), asymptotic analysis (ch. 3).
  • Weiss, Data Structures and Algorithm Analysis in C, 2nd ed. — linked lists and stacks (ch. 3), binary trees (ch. 4).
  • Deitel & Deitel, C++ How to Program, 10th ed. — class design and operator overloading (ch. 9–11), file streams (ch. 14).
  • Kernighan & Ritchie, The C Programming Language, 2nd ed. — arrays and file I/O (ch. 1, 7), pointers, structures and linked lists (ch. 5–6).
  • Stroustrup, The C++ Programming Language, 4th ed. — class templates and value semantics (ch. 3, 25–27).

The Computer Engineering citation list is built around architecture and networking texts (Patterson & Hennessy, Tanenbaum, Mano); this subject is programming and data structures, so the works above are cited instead.

Question 4: File I/O — Whitespace-Insensitive File Comparison (20 marks)

Question text not reproduced: the examination questions are © Engineers and Geoscientists BC. Open the official past paper (linked at the top of this page) to read the question, then follow the worked solution below.

Given. Two file names, read from standard input, whose contents are to be compared ignoring blanks, tabs and newlines; file sizes may differ.

Find. A boolean-returning routine that reports whether the two files are identical once all whitespace is stripped, exiting the moment a mismatch is provable.

Approach. Stream both files one character at a time with two independent cursors; at each step skip past any whitespace in either stream, then compare the next non-whitespace characters. Any character mismatch, or one file running out of non-whitespace content before the other, immediately returns false; both streams reaching EOF together with no mismatch returns true. This never buffers a whole file, satisfying the "early exit" and "different sizes" requirements simultaneously.

  1. Design the two-cursor skip-and-compare loop. Read one character from file A, skipping whitespace; read one from file B, skipping whitespace; if one stream hits EOF while the other still has a non-whitespace character, they differ; if both hit EOF together, they match; otherwise compare the two characters and stop immediately on any mismatch.
  2. Write the program.
    #include <stdio.h>
    #include <ctype.h>
    
    int next_significant(FILE *fp)
    {
        int c;
        while ((c = fgetc(fp)) != EOF && isspace(c))
            ;                       /* skip blanks, tabs, newlines */
        return c;                   /* EOF or the next real character */
    }
    
    int highly_similar(FILE *fa, FILE *fb)
    {
        int ca, cb;
    
        for (;;) {
            ca = next_significant(fa);
            cb = next_significant(fb);
            if (ca == EOF && cb == EOF) return 1;   /* both exhausted: match */
            if (ca != cb) return 0;                  /* mismatch or one is short */
        }
    }
    
    int main(void)
    {
        char name_a[256], name_b[256];
        FILE *fa, *fb;
        int result;
    
        printf("Enter first file name: ");
        scanf("%255s", name_a);
        printf("Enter second file name: ");
        scanf("%255s", name_b);
    
        fa = fopen(name_a, "r");
        fb = fopen(name_b, "r");
        if (!fa || !fb) { printf("false\n"); return 1; }
    
        result = highly_similar(fa, fb);
        printf(result ? "true\n" : "false\n");
    
        fclose(fa);
        fclose(fb);
        return 0;
    }
    
  3. Confirm the early-exit behaviour on two test cases. Comparing "int main() {\n return 0;\n}\n" against "int main(){return 0;}": stripping whitespace from both gives the identical stream int main(){return0;}, so the function consumes every character and returns true even though the raw files differ in length. Comparing that same file against "int main(){return 1;}": the mismatch is detected the instant the two whitespace-skipped cursors reach '0' vs. '1', without reading any further characters from either file. $$\boxed{\text{case 1: true (whitespace-only difference)};\ \ \text{case 2: false (content differs)}}$$
Question 4 — results
ComparisonResult
Same code, different whitespace/line breaks, equal significant contenttrue
Same code except one digit changed (0→1)false, detected at first differing character
One file has extra trailing non-whitespace textfalse, detected when the shorter file hits EOF first