Justine
Justine

Reputation: 7

File IO loops wrongly

I have a readFile function where it is supposed to identify the type of student from the text file. If its the nationality is local, it will create a localstudent class and store all the details into localstudent object and push_back into the vector. Same goes for international student. When i use cout to check how the vector in increasing in size, it will show the size increases 3 times so it means that my function is looping 3 times. How do i fix this?

input in file

Local   Bob 1 12 2003   Female  3   34  5345    345 3131    Bob 12313   1 12 2003   12 12 2000  1231    3   3   4   115.476 1346.48 258.75  4   234
Local   Tom 1/12/2003   male    3   34  5345    345 3131    Tom 12313   1/12/2003   12/12/2000  1231    3   3   4   115.476 1346.48 258.75  4   234

Output will show details of Bob once and Tom twice. I know that in.eof() is wrong but i do not know any other ways to loop for this.

void readFile(vector <clsStudent*> &s)
{
    string name, IC_no,state, gender, accNumb, accName, progName, ReadNationality, progCode, passportNumber, nation, visa, scholarship;
    int accID, times;
    float GPA, discountedFees, principle, rate, years, CI, C_Amount, progFees;
    clsDate DOB, accStart, accDOB, expDate;

    string line;
    ifstream in(filename);
    while(in)
    {

       if(in)
        {
            in >> ReadNationality;
            in >> name;
            in >> DOB;
            in >> gender;
            in >> GPA;
            in >> progName;
            in >> progCode;
            in >> progFees;
            in >> accNumb;
            in >> accName;
            in >> accID;
            in >> accDOB;
            in >> accStart;
            in >> principle;
            in >> rate;
            in >> years;
            in >> times;
            in >> CI;
            in >> C_Amount;
            in >> discountedFees;

            if (ReadNationality == "Local")
            {
                clsLocalStudent *stud;
                stud = new clsLocalStudent();
                in >> IC_no;
                in >> state;
                clsUniversityProgram *program= new clsUniversityProgram(progName, progCode, progFees);
                clsAccount objAccount(accNumb,name,accID, accDOB, accStart, principle, rate, years, times);

                stud->setName(name);
                stud->setDateOfBirth(DOB);
                stud->setGender(gender);
                stud->setNationality(ReadNationality);
                stud->setGPA(GPA);
                stud->setProgram(program);
                stud->setAccounts(objAccount);
                stud->setIC(IC_no);
                stud->setState(state);
                s.push_back(stud);
            }
            else
            {
                clsInternationalStudent *stud;
                stud = new clsInternationalStudent();
                in >> passportNumber;
                in >> nation;
                in >> visa;
                in >> expDate;
                in >> scholarship;
                clsUniversityProgram program(progName, progCode, progFees);
                clsAccount objAccount(accNumb,name,accID, accDOB, accStart, principle, rate, years, times);

                stud->setName(name);
                stud->setDateOfBirth(DOB);
                stud->setGender(gender);
                stud->setNationality(ReadNationality);
                stud->setGPA(GPA);
                stud->setProgram(&program);
                stud->setAccounts(objAccount);
                stud->setPassportNo(passportNumber);
                stud->setNation(nation);
                stud->setStudentVisa(visa);
                stud->setExpiryDate(expDate);
                stud->setScholarship(scholarship);
                s.push_back(stud);
            }
        }
        else
        cerr << "\nCannot open " << filename << " for reading" << endl;
    cout << s.size();
    }



    in.close();
}

void operator >> (istream &is, clsDate &date)
{
    string inputDate;
    int dd, mm, yy;
    char separator;

    is >> dd >> separator >> mm >> separator >> yy;

    date.setSeparator(separator);
    date.setMM(mm);
    date.setDD(dd);
    date.setYY(yy);
}

Upvotes: 0

Views: 63

Answers (2)

Daniel
Daniel

Reputation: 2185

Change your readFile() function as below,

void readFile(vector <clsStudent*> &s)
{
    string name, IC_no,state, gender, accNumb, accName, progName, ReadNationality, progCode, passportNumber, nation, visa, scholarship;
    int accID, times;
    float GPA, discountedFees, principle, rate, years, CI, C_Amount, progFees;
    clsDate DOB, accStart, accDOB, expDate;

    string line;
    ifstream in(filename);
    if (in.is_open())
    {
        while(in >> ReadNationality >> name
            >> DOB >> gender >> GPA
            >> progName >> progCode >> progFees
            >> accNumb>> accName>> accID
            >> accDOB>> accStart>> principle
            >> rate>> years>> times
            >> CI>> C_Amount>> discountedFees
        )
        {
            if (ReadNationality == "Local")
            {
                clsLocalStudent *stud;
                stud = new clsLocalStudent();
                in >> IC_no;
                in >> state;
                clsUniversityProgram *program= new clsUniversityProgram(progName, progCode, progFees);
                clsAccount objAccount(accNumb,name,accID, accDOB, accStart, principle, rate, years, times);

                stud->setName(name);
                stud->setDateOfBirth(DOB);
                stud->setGender(gender);
                stud->setNationality(ReadNationality);
                stud->setGPA(GPA);
                stud->setProgram(program);
                stud->setAccounts(objAccount);
                stud->setIC(IC_no);
                stud->setState(state);
                s.push_back(stud);
            }
            else
            {
                clsInternationalStudent *stud;
                stud = new clsInternationalStudent();
                in >> passportNumber;
                in >> nation;
                in >> visa;
                in >> expDate;
                in >> scholarship;
                clsUniversityProgram program(progName, progCode, progFees);
                clsAccount objAccount(accNumb,name,accID, accDOB, accStart, principle, rate, years, times);

                stud->setName(name);
                stud->setDateOfBirth(DOB);
                stud->setGender(gender);
                stud->setNationality(ReadNationality);
                stud->setGPA(GPA);
                stud->setProgram(&program);
                stud->setAccounts(objAccount);
                stud->setPassportNo(passportNumber);
                stud->setNation(nation);
                stud->setStudentVisa(visa);
                stud->setExpiryDate(expDate);
                stud->setScholarship(scholarship);
                s.push_back(stud);
            }
        }
        cout << s.size();
        in.close();
    }
    else
        cerr << "\nCannot open " << filename << " for reading" << endl;

}

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182865

You're expecting while (in), and the redundant, if (in) to predict the future and somehow guarantee that a future read will work. Of course, they can't do that. Instead, check each input operation to make sure it succeeds, and as soon as one fails, abort your loop.

The easiest way is probably to check the status of in after the last read and before you process any of the data read.

Upvotes: 3

Related Questions