user798774
user798774

Reputation: 413

How do i compare two files character by character

I'm writing a program that compares two files character by character. The function to compare each file returns a value dependant on the condition of the files.

the function returns 0 when both files are the same, -1 if both files match but the first file ends before the second, -2 if both files match but the second file ends before the first, and a positive int indicating which character the files differ at.

#include <stdio.h>
#include <string.h>
#define CMP_EQUAL 0
#define CMP_EOF_FIRST -1
#define CMP_EOF_SECOND -2

int char_cmp(FILE *fp1, FILE *fp2);

int main(void)
{
    FILE *fp1;
    FILE *fp2;

    fp1 = fopen("input1.txt", "rb+");
    fp2 = fopen("input2.txt", "rb+");

    switch(char_cmp(fp1, fp2))
    {
        case CMP_EQUAL:
            printf("The Files are equal");
            break;
        case CMP_EOF_FIRST:
            printf("EOF on a.txt");
            break;
        case CMP_EOF_SECOND:
            printf("EOF on t.txt");
            break;
        default:
            printf("files differ: char %d\n", char_cmp(fp1, fp2));
            break;
    }

    if(fclose(fp1) != 0)
    {
        perror("fclose");
        /*other error handling*/
    }

    if(fclose(fp2) != 0)
    {
        perror("fclose");
        /*other error handling*/
    }

    return 0;
}

int char_cmp(FILE *fp1, FILE *fp2)
{
    int c, d;
    size_t byte = 0;
    int same = 1;

    do
    {
        byte++;
    }while((c = fgetc(fp1)) == (d = fgetc(fp2)));

    if(c == EOF && d != EOF)
    {
        return CMP_EOF_FIRST;
    }

    if(d == EOF && c != EOF)
    {
        return CMP_EOF_SECOND;
    }

    if(c != d)
    {
        return byte;
    }

    return CMP_EQUAL;
}

I was wondering how i would break out of the do loop after checking if all the characters match in each file. Because when i have tried, It breaks the moment it finds a character that is the same and does not check the rest of it.

Also i've encourtered this weird bug where if one file contains:

dee

and the second one contains

ae

it gives me a weird return value and was wondering why is that so?

thanks for any help in advance

Upvotes: 1

Views: 4909

Answers (3)

Grigor Gevorgyan
Grigor Gevorgyan

Reputation: 6853

You call char_cmp(fp1, fp2)) twice - once in the switch statement, and the second time in the default condition. The second time it returns you the second char position in which they differ (or something another, really unexpected :)
Change it to

int k = char_cmp(fp1, fp2));

and use k in these both places:

switch( k )
...
printf("files differ: char %d\n", k);

EDIT: The infinite loop in case of equal files happens because in this condition:

(c = fgetc(fp1)) == (d = fgetc(fp2))

c and d become forever equal to EOF from some moment. Change it to

(c = fgetc(fp1)) == (d = fgetc(fp2) && c != EOF

and everything is ok.

Upvotes: 3

David Heffernan
David Heffernan

Reputation: 613521

You are calling char_cmp() multiple times. The second time round, in the printf() call, returns a different value from the first call because the file pointers have been used.

Call char_cmp() once and store the returned value in a local.

cmp = char_cmp(fp1, fp2);
switch(cmp)
{
case CMP_EQUAL:
    printf("The Files are equal");
    break;
case CMP_EOF_FIRST:
    printf("EOF on a.txt");
    break;
case CMP_EOF_SECOND:
    printf("EOF on t.txt");
    break;
default:
    printf("files differ: char %d\n", cmp);
    break;
}

I don't know whether the rest of your logical is correct or not.


Actually, your logic is not correct. It enters an infinite loop when presented with identical files. I'm sure you'll be able to track down the problem!

Upvotes: 3

ShinTakezou
ShinTakezou

Reputation: 9681

When both reach EOF at the same time, the while condition is true and you start looping over and over, since EOF == EOF.

I suggest you to try to be less "short" at the beginning.

Upvotes: 2

Related Questions