Problem with a diff algorithm

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Eric Boutin

    #1

    Problem with a diff algorithm

    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(zonefilenam e.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,bu ff2).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.loca l. IN A 192.168.0.101
    deepspace9.loca l. IN A 192.168.0.100


  • Ivan Vecerina

    #2
    Re: Problem with a diff algorithm

    "Eric Boutin" <ericb@nic.nac. wdyn.de> wrote in message
    news:pan.2004.1 2.05.21.02.07.5 03790@nic.nac.w dyn.de...[color=blue]
    > 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[/color]
    I'll try to point-out mistakes I see while reading on-the-fly
    [color=blue]
    > //returns true if it find a difference
    > bool diff(string currzone, string zonefilename, ostream& verbose) {
    > istringstream iss(currzone); //The Current Zone File
    > ifstream ifs(zonefilenam e.c_str()); //The Old Zone File
    > string buff1, buff2;
    > //ignore the first 8 lines
    > for(int i=1; i<8; i++) {[/color]
    Note that this loop will actually execute 7 times, not 8 !
    Could this be the problem?
    Try:
    for( int i = 0 ; i<8 ; ++i )[color=blue]
    > 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,bu ff2).eof() ==
    > true)) {
    > //everythings ok
    > verbose << "Both file ends at same time, no diff" << endl;
    > return false;}[/color]
    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,buf f1);
    bool ok2 = getline(ifs,buf f2);
    if( !ok1 && !ok2 ) return true;
    if( ok1 != ok2 ) return false; // either file is shorter
    // NB: print more detail if desired
    [color=blue]
    > 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[/color]
    Then you may want to add something like: assert(false);[color=blue]
    > return true;
    >
    > }[/color]


    I hope this helps,
    Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form


    Comment

    • Eric Boutin

      #3
      Re: Problem with a diff algorithm

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

      thanks !

      Comment

      • Buster

        #4
        Re: Problem with a diff algorithm

        Eric Boutin wrote:[color=blue]
        > fixed !
        > I based my algorithm on what you gave me and now it seems to work
        >
        > thanks ![/color]

        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,bu ff2).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.

        --
        Regards,
        Buster

        Comment

        • Eric Boutin

          #5
          Re: Problem with a diff algorithm

          Le Mon, 06 Dec 2004 02:01:00 +0000, Buster a écrit :
          [color=blue]
          > 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.[/color]

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

          Comment

          Working...