JennyMack
JennyMack

Reputation: 13

C++ program reading every other line of input file, instead of every line

I am working on a homework assignment that calculates GPA's and course averages using an external file. The code is not completely fleshed out, but I've built it out enough that it should be able to at least show me that it can pull the data from the external file (a plain text file created in TextWrangler), and calculate the figures.

However, when I run it, it only seems to be pulling every other line of the output file. Any ideas of where I could be going wrong?

#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;

int main()
{

    int studentID, studentCounter=0;
    double grade1, grade2, grade3, grade4, course1Sum=0, course2Sum=0, course3Sum=0, course4Sum=0, course1Average, course2Average, course3Average, course4Average, GPA;
    ifstream inputFile;
    string filename;

    for (int x=1; x<=3; x++) {

        // Get the filename from the user.
        // /Users/etc/Desktop/HW5test.txt - valid set
        // /Users/etc/Desktop/HW5testset.txt - test set


        cout<<"Enter the filename: ";
        cin>>filename;

        // Open the file.
        inputFile.open(filename.c_str());
        // If the file successfully opened, process it.
        if (inputFile) {
            // Read the numbers from the file and display them.
            while (inputFile>>studentID>>grade1>>grade2>>grade3>>grade4)
            {
                if (studentCounter==0) // Prints header if at the start of the program.
                    cout<<"Header placeholder"<<endl;

                inputFile>>studentID>>grade1>>grade2>>grade3>>grade4;
                GPA=(grade1+grade2+grade3+grade4)/4;
                cout<<studentID<<" "<<GPA<<" "<<"Special message (if needed)."<<endl;

                // Course Average and Student Accumulators
                course1Sum+=grade1;
                course2Sum+=grade2;
                course3Sum+=grade3;
                course4Sum+=grade4;
                studentCounter++;

            } // Ends while() loop.

            if (studentCounter==0)
                cout<<"File contains no data."<<endl;

            else {

            // Perform course averages here, after all data has been read.
            course1Average=course1Sum/studentCounter;
            cout<<"Course 1 average: "<<course1Average<<endl;
            course2Average=course2Sum/studentCounter;
            cout<<"Course 2 average: "<<course2Average<<endl;
            course3Average=course3Sum/studentCounter;
            cout<<"Course 3 average: "<<course3Average<<endl;
            course4Average=course4Sum/studentCounter;
            cout<<"Course 4 average: "<<course4Average<<endl<<endl;

            } // Ends "else" of file empty error check.

            // Close the input file.
            inputFile.close();
        } // Ends "if" of if/else().
        else {
            cout<<"Error opening the file.\n";
        } // Ends "else" of if/else().


    } // Ends for() loop.

    return 0;
} // Ends main().

The input file data:

1001 3.0 2.7 2.0 2.8 
1002 3.7 3.5 4.0 4.0 
1003 0.0 1.0 2.2 1.0 
1004 4.0 3.0 3.5 3.5 

My output looks like this (keep in mind, still working on pieces, but see that it's only pulling every other entry:

Enter the filename: /Users/etc/Desktop/HW5testset.txt
Header placeholder
1002 3.8 Special message (if needed).
1004 3.5 Special message (if needed).
Course 1 average: 3.85
Course 2 average: 3.25
Course 3 average: 3.75
Course 4 average: 3.75

What could be going on?

Upvotes: 1

Views: 3896

Answers (3)

Code-Apprentice
Code-Apprentice

Reputation: 83527

By doing inputFile>>studentID>>grade1>>grade2>>grade3>>grade4 twice in your code, you read two lines of your input file each time the while loop iterates. You should remove one of these, probably the one inside the while loop.

Upvotes: 0

gotta have my pops
gotta have my pops

Reputation: 898

Your while loop already reads the input stream into studentID, grade1, grade2, grade3, grade4.

They are already set in each iteration of the loop. By reading the input stream again after printing your header, you are updating your variables, which is why you're reading all the even numbered lines.

while (inputFile>>studentID>>grade1>>grade2>>grade3>>grade4) { // reads 1001
    // grade1-grade4 are already set
    if (studentCounter==0) // Prints header if at the start of the program.
    cout<<"Header placeholder"<<endl;
    inputFile>>studentID>>grade1>>grade2>>grade3>>grade4; // reads 1002, remove this line
    GPA=(grade1+grade2+grade3+grade4)/4;
    ...

Upvotes: 0

Bob Fincheimer
Bob Fincheimer

Reputation: 18056

inputFile>>studentID>>grade1>>grade2>>grade3>>grade4 appears in your while statement and instide the while statement. Delete the instance that is not in the while condition (the one before GPA=.

You read the line in the while statement, then read the next line and therefore never see the first of the two lines. Just because the code is in the while() doesn't mean it doesn't have side-effects

EDIT

Also make your

if (studentCounter==0) // Prints header if at the start of the program.
    cout<<"Header placeholder"<<endl;

into:

if (studentCounter==0) { // Prints header if at the start of the program.
    studentCounter++;
    cout<<"Header placeholder"<<endl;
    continue;
}

Upvotes: 1

Related Questions