I wrote a program to compare two text files character by character and its not working probably an easy thing im just not seeing.

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

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

  string s1;
  string s2;
  char c1, c2;

  if(argc !=3) {         // check command line
    cerr << "Usage: " << argv[0] << " file1 file2" << endl;
    return 1;
  }

  ifstream ifs1( argv[1] ); // get file1
  if( !ifs1 ){
    cerr << "can't open " << argv[1] << endl;
    return 1;
  }

  ifstream ifs2( argv[2] ); // get file2
  if( !ifs2 ){
    cerr << "can't open " << argv[2] << endl;
    return 1;
  }

  for( int i = 0; !ifs2.eof(); i++ ){
    getline( ifs2, s2 );

    if( !ifs1.eof() ){
      getline( ifs1, s1 );

      c1 = s1[i];
      c2 = s2[i];
      if( c1 != c2 )
        cout << endl << "Files differ at line" << (i + 1) << endl;
    }
  }

  return(0);
}

well first of your calling getline twice. once after your for statement and once after your if statement. also you should not use eof() while reading to the end of the file. you can search around and find some good links about that. i would get rid of the for loop and just use a while loop like

while (getline(ifs1, s1) && getline(ifs2, s1))
{
       // your code here
       i++;  //  this will increment i so you don't need the for loop.
}

Edited 6 Years Ago by NathanOliver: n/a

Nathan is right. Change the for statement. You can better write the for as for (;!ifs2.eof();) which is really a while() Also, as he says, you read off the first line of file 2. Then

for( int i = 0; !ifs2.eof(); i++ ){
    getline( ifs2, s2 );  // Read line from file 2

    if( !ifs1.eof() ){
      getline( ifs1, s1 );  // Read line from file 1

      c1 = s1[i];       // get the first characters of each line
      c2 = s2[i];
      if( c1 != c2 )    // compare the first characters in each line
        cout << endl << "Files differ at line" << (i + 1) << endl;
    }
  }

So, if the first character if each line matches, the files are the same.

Here's why you don't want to use .eof() -- feof() in C is the same as .eof()

I wrote a program to compare two text files character by character and its not working probably an easy thing im just not seeing.

for( int i = 0; !ifs2.eof(); i++ ){
    getline( ifs2, s2 );

    if( !ifs1.eof() ){
      getline( ifs1, s1 );

      c1 = s1[i];
      c2 = s2[i];
      if( c1 != c2 )
        cout << endl << "Files differ at line" << (i + 1) << endl;
    }
  }

your line

c1 = s1

i is stepping for lines but you are only cheking the index every
i chars

you do not iterate across line so only are checking a diagonla of cahrs

my new updated code is this, i just need a way to count the char's in the string, I want to use gcount but I cant figure out the correct formatting.

heres my new updated code

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char *argv[]){
  string s1;
  string s2;
  char c1, c2;
  int line = 1;

  if(argc !=3) {         // check command line
    cerr << "Usage: " << argv[0] << " file1 file2" << endl;
    return 1;
  }

  ifstream ifs1( argv[1] ); // get file1
  if( !ifs1 ){
    cerr << "can't open " << argv[1] << endl;
    return 1;
  }

  ifstream ifs2( argv[2] ); // get file2
  if( !ifs2 ){
    cerr << "can't open " << argv[2] << endl;
    return 1;
  }

  while( getline( ifs1, s1 ) && getline( ifs2, s2 )){

    for( int i = 0; i < gcount( s1 ); i++ ){

      c1 = s1[i];
      c2 = s2[i];
      if( c1 != c2 )
        cout << endl << "Files differ at line" << (i + 1) << endl;
    }
    line++;
  }

  return(0);
}

Edited 6 Years Ago by Dewey1040: n/a

>> I want to use gcount but I cant figure out the correct formatting.
Since you are having two string s there, you can get a string's length using e.g. .length() I.e.

string test = "abc";
// the following would print 3 
cout << test.length() << endl;

But then again, you don't need actually that, because you can check whether two strings are identical by

string test1 = "abc";
string test2 = "abc";

// a case sensitive comparison ...
if(test1 == test2)
{
    cout << "strings are identical" << endl;
}

// or ...
if(test1 != test2)
{
    cout << "strings are not identical" << endl;
}

Then last but not least, you probably want to handle the case where the files don't contain the same number of lines. As of now, your program would not detect that.

One thing I'm wondering is if you are reading the entire line from both files, why are you checking character by character? Couldn't you just compare the lines as read? if (s1 != s2) You are using strings, which can be compared with ==

My assignment is to compare the files char by char... believe me i wouldn't be doing it this way if i didnt have to. we have to report the line the files are different so using getline makes that part easy.

The end of s1 will be where s1 == '\0'.
The end of s2 will be where s2 == '\0'.

cout << endl << "Files differ at line" << (i + 1) << endl;

i isn't the line number, line is.

My assignment is to compare the files char by char... believe me i wouldn't be doing it this way if i didnt have to. we have to report the line the files are different so using getline makes that part easy.

Another option then is to read the files one character at a time. When you read a \n, increment the line count.

I wouldn't change to this now, but next time it's something to consider.

This question has already been answered. Start a new discussion instead.