//******************************************************************
// CheckLists program
// There are two lists of positive integers in a data file,
// separated by a negative integer.  This program compares the two
// lists.  If they are identical, a message is printed.  If not,
// nonmatching pairs are printed.  Assumption: The number of values
// in both lists is the same and is <= 500
//******************************************************************
#include <iostream>
#include <iomanip>    // For setw()
#include <fstream>    // For file I/O
#include <string>     // For string class

using namespace std;

const int MAX_NUMBER = 500;     // Maximum in each list

void CompareLists( const int[], int, ifstream&, bool& );
void OpenForInput( ifstream& );
void ReadFirstList( int[], int&, ifstream& );

int main()
{
    int      firstList[MAX_NUMBER];   // Holds first list
    bool     allOK;                   // True if lists are identical
    int      numVals;                 // No. of values in first list
    ifstream dataFile;                // Input file

    OpenForInput(dataFile);
    if ( !dataFile )
        return 1;

    ReadFirstList(firstList, numVals, dataFile);
    allOK = true;
    CompareLists(firstList, numVals, dataFile, allOK);
    if (allOK)
        cout << "The two lists are identical" << endl;
    return 0;
}

//******************************************************************

void OpenForInput( /* inout */ ifstream& someFile )    // File to be
                                                       // opened
// Prompts the user for the name of an input file
// and attempts to open the file

// Postcondition:
//     The user has been prompted for a file name
//  && IF the file could not be opened
//         An error message has been printed
// Note:
//     Upon return from this function, the caller must test
//     the stream state to see if the file was successfully opened

{
    string fileName;    // User-specified file name

    cout << "Input file name: ";
    cin >> fileName;

    someFile.open(fileName.c_str());
    if ( !someFile )
        cout << "** Can't open " << fileName << " **" << endl;
}

//******************************************************************

void ReadFirstList(
           /* out */   int       firstList[],   // Filled first list
           /* out */   int&      numVals,       // Number of values
           /* inout */ ifstream& dataFile    )  // Input file

// Reads the first list from the data file
// and counts the number of values in the list

// Precondition:
//     dataFile has been successfully opened for input
//  && The no. of input values in the first list <= MAX_NUMBER
// Postcondition:
//     numVals == number of input values in the first list
//  && firstList[0..numVals-1] contain the input values

{
    int counter;    // Index variable
    int number;     // An input value

    counter = 0;
    dataFile >> number;
    while (number >= 0)
    {
        firstList[counter] = number;
        counter++;
        dataFile >> number;
    }
    numVals = counter;
}

//******************************************************************

void CompareLists(
   /* in */    const int       firstList[],   // 1st list of numbers
   /* in */          int       numVals,       // Number in 1st list
   /* inout */       ifstream& dataFile,      // Input file
   /* inout */       bool&     allOK       )  // True if lists match

// Reads the second list of numbers
// and compares it to the first list

// Precondition:
//     allOK is assigned
//  && numVals <= MAX_NUMBER
//  && firstList[0..numVals-1] are assigned
//  && The two lists have the same number of values
// Postcondition:
//     Values from the second list have been read from the
//     input file
//  && IF all values in the two lists match
//          allOK == allOK@entry
//     ELSE
//          allOK == false
//       && The positions and contents of mismatches have been
//          printed

{
    int counter;    // Loop control and index variable
    int number;     // An input value

    for (counter = 0; counter < numVals; counter++)
    {
        dataFile >> number;
        if (number != firstList[counter])
        {
            allOK = false;
            cout << "Position " << counter << ": "
                 << setw(4) << firstList[counter] << " != "
                 << setw(4) << number << endl;
        }
    }
}
