Problem with a diff algorithm

E

Eric Boutin

Hi all ! I'm currently writing a function that evaluate if there is a
diffence beetween 2 streams (istringstream and ifstream).

The problem is, it doesn't work. It *always* finds a difference at the
9th line because the first 8 lines are skipped, however, the is no
difference at all beetween the two streams, the only difference is that
after skipping the 8th first lines, one of the stream don't go forward
therefore a difference is found. Here's the function

//returns true if it find a difference
bool diff(string currzone, string zonefilename, ostream& verbose) {
istringstream iss(currzone); //The Current Zone File
ifstream ifs(zonefilename.c_str()); //The Old Zone File
string buff1, buff2;
//ignore the first 8 lines
for(int i=1; i<8; i++) {
getline(iss, buff1);
getline(ifs, buff2);
verbose << "Ignored from curr zone : " << buff1 << endl;
verbose << "ignored from old zone : " << buff2 <<endl;
}

while(true) {
if((getline(iss, buff1).eof() == true) && (getline(ifs,buff2).eof() == true)) {
//everythings ok
verbose << "Both file ends at same time, no diff" << endl;
return false;}

if(buff1 != buff2) {
//difference found
verbose << "Difference found :\n New Line : " << buff1
<< "\n Old Line : " << buff2 <<endl;
return true;
} else {
verbose << "Identic Lines : "<< endl << buff1 << endl << buff2 << endl;


}
}
//Shouldn't come up here
return true;

}

and the output produce when ostream& verbose = cout;

Ignored from curr zone : $ttl 38400
ignored from old zone : $ttl 38400
Ignored from curr zone : local. IN SOA enterprise. root.localhost. (
ignored from old zone : local. IN SOA enterprise. root.localhost. (
Ignored from curr zone : 2004211516 ;Serial Number
ignored from old zone : 2004211516 ;Serial Number
Ignored from curr zone : 10800 ; refresh
ignored from old zone : 10800 ; refresh
Ignored from curr zone : 3600 ; retry
ignored from old zone : 3600 ; retry
Ignored from curr zone : 604800 ; expire
ignored from old zone : 604800 ; expire
Ignored from curr zone : 3600 ) ; minimum
ignored from old zone : 3600 ) ; minimum
Difference found :
New Line : local. IN NS enterprise.
Old Line : 3600 ) ; minimum

We can notice the "old line" "forget" to go forward.. I really don't know
what's wrong

(thoses who works in DNS area will notice it's a BIND zone file..)

I really really don't know what's wrong and I really appreciate your help !
thanks a lot !

by the way.. English is not my main langage so excuse my errors.. thanks !


if it can help (that's why it's at the end since I'm not so shure it can
help but I just provides it) Here's the zone file produced by this program
(the same one that's read)

$ttl 38400
local. IN SOA enterprise. root.localhost. (
2004211516 ;Serial Number
10800 ; refresh
3600 ; retry
604800 ; expire
3600 ) ; minimum
local. IN NS enterprise.
josee.local. IN A 192.168.0.102
enterprise.local. IN A 192.168.0.101
deepspace9.local. IN A 192.168.0.100
 
I

Ivan Vecerina

Eric Boutin said:
Hi all ! I'm currently writing a function that evaluate if there is a
diffence beetween 2 streams (istringstream and ifstream).

The problem is, it doesn't work. It *always* finds a difference at the
9th line because the first 8 lines are skipped, however, the is no
difference at all beetween the two streams, the only difference is that
after skipping the 8th first lines, one of the stream don't go forward
therefore a difference is found. Here's the function
I'll try to point-out mistakes I see while reading on-the-fly
//returns true if it find a difference
bool diff(string currzone, string zonefilename, ostream& verbose) {
istringstream iss(currzone); //The Current Zone File
ifstream ifs(zonefilename.c_str()); //The Old Zone File
string buff1, buff2;
//ignore the first 8 lines
for(int i=1; i<8; i++) {
Note that this loop will actually execute 7 times, not 8 !
Could this be the problem?
Try:
for( int i = 0 ; i<8 ; ++i )
getline(iss, buff1);
getline(ifs, buff2);
verbose << "Ignored from curr zone : " << buff1 << endl;
verbose << "ignored from old zone : " << buff2 <<endl;
}

while(true) {
if((getline(iss, buff1).eof() == true) && (getline(ifs,buff2).eof() ==
true)) {
//everythings ok
verbose << "Both file ends at same time, no diff" << endl;
return false;}
The previous is not correct: a difference in the last line of both
files may be discarded ! (the eof() flag is set if line extraction
is successful but ends with hitting the end of the file).
Try:
bool ok1 = getline(iss,buff1);
bool ok2 = getline(ifs,buff2);
if( !ok1 && !ok2 ) return true;
if( ok1 != ok2 ) return false; // either file is shorter
// NB: print more detail if desired
if(buff1 != buff2) {
//difference found
verbose << "Difference found :\n New Line : " << buff1
<< "\n Old Line : " << buff2 <<endl;
return true;
} else {
verbose << "Identic Lines : "<< endl << buff1 << endl << buff2 <<
endl;


}
}
//Shouldn't come up here
Then you may want to add something like: assert(false);
return true;

}


I hope this helps,
Ivan
 
E

Eric Boutin

fixed !
I based my algorithm on what you gave me and now it seems to work

thanks !
 
B

Buster

Eric said:
fixed !
I based my algorithm on what you gave me and now it seems to work

thanks !

The problem was as Ivan said. You should use fail (), not eof (), to
find out when you've finished reading a stream. It might be useful to
read the input/output section of the FAQ. People make fairly similar
errors quite often.

As for the strange behaviour (finding a difference in two identical
files), find out about short-circuit evaluation for the built-in &&
and || operators. It's not in the FAQ so use google.

if((getline(iss, buff1).eof() == true) && (getline(ifs,buff2).eof() ==
true)) {
// So far so good. We get here only if both getlines were
// executed and both streams now have eofbit set in rdstate().
// (That's not what we meant, but still ...)
} else {
// Trouble. If the first getline didn't set eofbit in iss.rdstate()
// then the second getline never got executed, so buff2 keeps its
// old value.
}

Either you can do what Ivan did and make sure both getlines are
executed every time round the loop, or you can arrange for the
short-circuit to kick in when there's a failure, rather than when
there's a success.
 
E

Eric Boutin

Le Mon, 06 Dec 2004 02:01:00 +0000, Buster a écrit :
As for the strange behaviour (finding a difference in two identical
files), find out about short-circuit evaluation for the built-in &&
and || operators. It's not in the FAQ so use google.

Thanks ! I really tought both instructions would be executed but I guess
I was wrong.. Thanks for your help !
 

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top