1

My program compares two text files and puts the differences in file one in a third text file. However, when my file one's size is larger than my file two's size a 'ÿ' character is placed at the end of the third file. For example suppose file one consists of "I like pickles." and file two consists of "I like dogs." then the third file will consist of "pickles.ÿ". Is there a way to get rid of this? And why is this happening? Here is my program:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{

    int ch1, ch2;
    int size1, size2;
    FILE *fh1, *fh2, *diffone=stdout;

    if( argc<3 ) {
        printf("need two file names\n"); return(1);
    }
    if(!(fh1 = fopen(argv[1], "r"))) {
        printf("cannot open %s\n",argv[1]); return(2);
    }
    if(!(fh2 = fopen(argv[2], "r"))) {
        printf("cannot open %s\n",argv[2]); return(3);
    }
    if(argc>3) {
        if(!(diffone = fopen(argv[3], "w+"))) {
            printf("cannot open %s\n",argv[3]); return(4);
        }
    }

    fseek(fh1, 0, SEEK_END);
    size1 = ftell(fh1);//gets size of fh1
    fseek(fh1, 0, SEEK_SET);

    fseek(fh2, 0, SEEK_END);
    size2 = ftell(fh2);//gets size of fh2
    fseek(fh2, 0, SEEK_SET);

    while((!feof(fh1)) || (!feof(fh2)))
    {
        ch1=ch2='-';
        if(!feof(fh1)) ch1 = getc(fh1);
        if(!feof(fh2)) ch2 = getc(fh2);
    if (size2 > size1)
      {
        if(ch1 != ch2 && (!feof(fh1)))
          {
        fprintf(diffone,"%c", ch1);
          }
      }
    else 
      {
        if (ch1 != ch2)
          {
        fprintf(diffone,"%c", ch1);
          }
      }

    }
}
user2264035
  • 565
  • 1
  • 7
  • 13
  • Without looking at it too much, the problem descriptions sounds like the last char being uninitialzed memory, thus you probably have an off-by-one problem. Again, only guessed, I may be wrong. – JensG Nov 01 '13 at 20:28
  • 1
    possible duplicate of ["while( !feof( file ) )" is always wrong](http://stackoverflow.com/questions/5431941/while-feof-file-is-always-wrong) – Roddy Nov 01 '13 at 20:32

4 Answers4

3

feof() only returns true after fgetc() has returned EOF (-1).

See Why is “while ( !feof (file) )” always wrong?

Community
  • 1
  • 1
Roddy
  • 66,617
  • 42
  • 165
  • 277
0

You are not doing any error checking on fgetc(), and you are not checking for EOF on fh2 when size1 > size2.

Try this instead:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int ch1, ch2;
    int eof1 = 0, eof2 = 0;
    FILE *fh1, *fh2, *diffone=stdout;

    if (argc < 3) {
        printf("need two file names\n");
        return(1);
    }
    if (!(fh1 = fopen(argv[1], "r"))) {
        printf("cannot open %s\n",argv[1]);
        return(2);
    }
    if (!(fh2 = fopen(argv[2], "r"))) {
        printf("cannot open %s\n",argv[2]);
        return(3);
    }
    if (argc > 3) {
        if (!(diffone = fopen(argv[3], "w+"))) {
            printf("cannot open %s\n",argv[3]);
            return(4);
        }
    }

    while(1)
    {
        if (!eof1) {
            ch1 = fgetc(fh1);
            if (ch1 == EOF) {
                if (ferror(fh1)) {
                    printf("cannot read from %s\n",argv[1]);
                    return(5);
                }
                eof1 = 1;
            }
        }
        else {
          ch1 = '-';
        }

        if (!eof2) {
            ch2 = fgetc(fh2);
            if (ch2 == EOF) {
                if (ferror(fh2)) {
                    printf("cannot read from %s\n",argv[2]);
                    return(6);
                }
                eof2 = 1;
            }
        }
        else {
            ch2 = '-';
        }

        if ((eof1) && (eof2))
            break;

        if ((ch1 != ch2) || (eof1 != eof2)) {
            if (fputc(ch1, diffone) == EOF) {
                if (argc > 3) {
                    printf("cannot write to %s\n",argv[3]);
                }
                return(7);
            }
        }
    }
    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
0

Check EOF after each fgetc().
Avoid using feof(). Recall feof() becomes true after an EOF was first returned from a read.

Instead of

while((!feof(fh1)) || (!feof(fh2))) {
    if(!feof(fh1)) ch1 = getc(fh1);
    if(!feof(fh2)) ch2 = getc(fh2);

Use

 while (1) {
   ch1 = fget(fh1);
   ch2 = fget(fh2);
   if (ch1 == EOF) { 
     if (ch2 == EOF) break;
     ch1 = '-';
   }
   if (ch2 == EOF) { 
     ch2 = '-';
   }
   ....
 }
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

This problem occurs when you are trying to fetch from file first and then print for example-

ch=fgetc(fp2);
while(ch!=EOF)
{   
    ch = fgetc(fp2);
    fputc(ch, fp1);     
}

INSTEAD DO-

ch=fgetc(fp2);
while(ch!=EOF)
{   
   fputc(ch, fp1);
   ch = fgetc(fp2);
}