Jose Meza
Jose Meza

Reputation: 71

c++ input data reading incorrectly

I am having a problem reading my input file. the program reads the input file perfectly and works great except for the fact that it reads the last persons name in the document twice.

here is part of the program output showing hooper, grace name twice. thanks for looking

****Input file lab10data1.txt is open for reading.
Number of student records read = 17
The following student(s) have the highest score
 Einstein, Albert
List of All the Students in the class
 Student Name          Test Score     Grade
 ------------------------------------------
 Fibonacci, Leonardo        63         D
      Huffman, David        79         C
        Augusta, Ada        91         A
 Goldbach, Christian        81         B
          Venn, John       100         A
      Church, Alonzo        72         C
    Einstein, Albert       105         F
      Fermat, Pierre        84         B
     Kruskal, Joseph        66         D
       Cantor, Georg        67         D
        Turing, Alan        85         B
      Chebysheva, PL       100         A
  DeMorgan, Augustus        79         C
   Karnaugh, Maurice        72         C
    Babbage, Charles        98         A
       Hooper, Grace        95         A
       Hooper, Grace        95         A // RIGHT HERE it reads grace twice

this is the code

    #include<iostream>
    #include<fstream>
    #include<string>
    #include<iomanip>**


using namespace std;

struct StudentType
{
    string studentName;
    int testScore;//Between 0 and 100
    char grade;
};

void PrintNameHeader(ostream& out);
bool OpenInputFile(ifstream& inFile, string& infilename ); //OPEN input file
void Pause();// Pause
void ReadStudentData(ifstream& infile, StudentType student[], int& );// Read student infp including first and last name and test score
void AssignGrades(StudentType student[], int);//assign grades to each student
int HighestScore(const StudentType student[], int );//Get the highest scores
void PrintNamesWithHighestScore(const StudentType student[], int);//Print name/s with highest Scores
void DisplayAllStudents(const StudentType student[], int);//Display all students
void GetLowHighRangeValues(const StudentType student[], int, int& , int&);//for example a student types 50 100 , it will get all students within that range
void DisplayStudentsInRange(const StudentType student[], int, int, int);// display students in that range
void SortStudentsByName(StudentType student[], int);// sort students by name
void SortStudentsByScore(StudentType student[], int);// sort students by test score highest to lowest
void FormatNameScoreGrade(ostream& out);


const int NUM_STUDENTS = 20;

int main()
{
    ifstream infile;
    string inFilename;
    StudentType student[NUM_STUDENTS];
    int numStudents = 0;

    PrintNameHeader(cout);

    if(!OpenInputFile(infile,inFilename)) return 1;

    ReadStudentData(infile, student, numStudents);
    infile.close();

    AssignGrades(student, numStudents);

    PrintNamesWithHighestScore(student, numStudents);

    cout <<"List of All the Students in the class" << endl;
    DisplayAllStudents(student, numStudents);

    Pause();//Pause

    int lownum, highnum;
    char answer;

    do {

        GetLowHighRangeValues(student, numStudents, lownum, highnum);

        DisplayStudentsInRange(student, numStudents, 70, 90);
        cout <<"Do you want to see another range of scores [y/n]?";
        cin >> answer;
    } while( answer == 'y' || answer == 'Y');

    SortStudentsByName(student, numStudents);
    Pause();//Pause

    SortStudentsByScore(student, numStudents);

    return 0;
}

//Function definitions

void PrintNameHeader(ostream& out)
{
    //Display name header on screen


}

void FormatNameScoreGrade(ostream& out)
{
    out  << setw(10) << " Student Name" << setw(20) <<"Test Score" << setw(10) <<"Grade" << endl;
    out <<" ------------------------------------------" << endl;
}

bool OpenInputFile(ifstream& inFile, string& infilename) 
{
    cout << "Enter the name of the .txt file that you want to open for input.\n";
    cout << "Do not put spaces in the file name : ";
    cin >> infilename;
    cout << endl;

    inFile.open(infilename.c_str());
    if (inFile.fail())
    {
        cout << "Sorry, the input file " << infilename <<" was not found"<< endl;\
            return false;
    }

    cout << "Input file " << infilename << " is open for reading.\n\n";
    return true;
}

void Pause()
{
    cout << endl;
    cin.ignore(80, '\n');
    cout<<"Please hit the enter key to continue...\n";
    cin.get();
}

void ReadStudentData(ifstream& infile, StudentType student[], int& numStudents)
{
    string firstName, lastName;
    int testScore;
    int count = 0;

    while(infile)
    {
        infile >> firstName >> lastName >> testScore;
        student[count].studentName = lastName + ", " + firstName;
        student[count].testScore = testScore;
        count++;
    }

    numStudents = count;
    cout << "Number of student records read = " << numStudents << endl;
}

void AssignGrades(StudentType student[], int numStudents)
{

    int testscore;
    char grade;

    for(int i = 0; i < numStudents; i++)
    {
        testscore = student[i].testScore;

        if(testscore >= 90 && testscore <=100)
            grade = 'A';
        else if(testscore >= 80 && testscore <90)
            grade = 'B';
        else if(testscore >= 70 && testscore <80)
            grade = 'C';
        else if(testscore >= 60 && testscore <70)
            grade = 'D';
        else
            grade = 'F';

        student[i].grade = grade;
    }
}

int HighestScore(const StudentType student[], int numStudents)
{
    int highest = student[0].testScore;

    for(int i = 1; i < numStudents; i++)
    {
        if(highest < student[i].testScore) highest = student[i].testScore;
    }

    return highest;
}

void PrintNamesWithHighestScore(const StudentType student[], int numStudents)
{
    int highest = HighestScore(student, numStudents);
    cout << endl << "The following student(s) have the highest score" << endl << endl;
    for(int i = 0; i < numStudents; i++)
    {
        if (student[i].testScore == highest)
        {
            cout << " " << student[i].studentName;
        }
    }

    cout << endl;
}

void DisplayAllStudents(const StudentType student[], int numStudents)
{
    cout << endl;

    FormatNameScoreGrade(cout);

    for(int i = 0; i < numStudents; i++)
    {

        cout << setw(20) << student[i].studentName << setw(10) << student[i].testScore << setw(10) << student[i].grade << endl;
    }

    cout << endl;
}

void GetLowHighRangeValues(const StudentType student[], int numStudents, int& lowRange, int& highRange)
{
    int lowest = student[0].testScore;

    for(int i = 1; i < numStudents; i++)
    {
        if(lowest > student[i].testScore) lowest = student[i].testScore;
    }

    lowRange = lowest;
    highRange = HighestScore(student, numStudents);
}

void DisplayStudentsInRange(const StudentType student[], int numStudents, int lownum, int highnum)
{
    cout <<"Enter two vales for the range of scores you want to look at: ";
    cin >> lownum >> highnum;






    cout << endl << "List of students with scores in the range " << lownum << " to " << highnum << endl << endl;
    FormatNameScoreGrade(cout);


    for(int i = 0; i < numStudents; i++)
    {
        if(student[i].testScore >= lownum && student[i].testScore <= highnum)
        {

            cout << setw(20) << student[i].studentName << setw(10) << student[i].testScore << setw(10) << student[i].grade << endl;
        }
    }
    cout << endl;
}

void SortStudentsByName(StudentType student[], int numStudents)
{
    StudentType temp;

    for(int i = 0;i < numStudents - 1;i++)
    {
        for(int j = i + 1; j < numStudents;j++)
        {
            if(student[i].studentName > student[j].studentName)
            {
                temp = student[i];
                student[i] = student[j];
                student[j] = temp;
            }
        }
    }

    cout << endl;
    cout << "List of Students sorted by Name" << endl;
    DisplayAllStudents(student, numStudents);
}

void SortStudentsByScore(StudentType student[], int numStudents)
{
    StudentType temp;

    for(int i = 0;i < numStudents - 1;i++)
    {
        for(int j = i + 1; j < numStudents;j++)
        {
            if(student[i].testScore < student[j].testScore)
            {
                temp = student[i];
                student[i] = student[j];
                student[j] = temp;
            }
        }
    }

    cout <<"List of Students sorted by Score" << endl;
    DisplayAllStudents(student, numStudents);
}

Upvotes: 1

Views: 518

Answers (1)

David G
David G

Reputation: 96835

Change:

while (infile)
{
    infile >> firstName >> lastName >> testScore;
// ...

to

while (infile >> firstName >> lastName >> testScore)
{
// ...

so that the read is performed before checking the stream.

Upvotes: 1

Related Questions