-1

I'm making a program to calculate student's quiz averages and class average, while using a loop to simplify it and storing the data to a file (just a .txt for now).

I'm new to c++ and this is probably the most advanced thing I've worked on so far...

My current code is:

// Grade Average calculator

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

int main(){
    ofstream outputFile;
    ifstream inputFile;
    int continueYes;
    double  qz, score;
    string studentId;

    //Open File
    outputFile.open("quizav.txt");
    //Continue to start...
    cout << "Press 1 to add a student, Press 0 to exit.\n";
    cin >> continueYes;

    while (continueYes == 1){
        cout << "Please Enter student ID: ";
        cin >> studentId;

        outputFile << studentId << " ";

        for (qz = 1; qz < 5; qz++){
            cout << "Enter quiz score " << qz << " ";
            cin >> score;

            +-score;
            outputFile << " " << score << " ";
        }

        cout << "Press 1 to add a student, press 0 if no more.\n";
        cin >> continueYes;
        outputFile << " " << endl;

    }

    outputFile.close();

    //OUT PUT FINISHED
    double average;
    double student, studentInfo;
    inputFile.open("quizav.txt");

    while (inputFile >> studentInfo){

        cout << studentInfo << endl;
    }

    system("pause");
    return 0;
}

While the top half works fine, and stores the information in a text file like so

student id  score, score, score
student id  score, score, score
etc.

I am not sure what to make my while and for loop on the bottom to give output roughly to my desired:

student 1's average: average student 2's average: average etc

class average:

The current While/for loop at the bottom display the right information from the file, just not in the right matter (no gaps between student IDs)

I really need it to get one line at a time, average it, and store the total to average it later.

Thank you for any help.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Ace Ebert
  • 71
  • 1
  • 2
  • 7
  • 1
    Did you already step through the reading part with a debugger line by line? May be you rather want to use `std::getline()` to read a whole record 1st, and split for the interesting values in it (e.g. using `std::istringstream`). – πάντα ῥεῖ Mar 30 '15 at 18:47
  • I attempted to use a getline, but it would not work with how I had it, could you use an example of one of these? It doesn't need to be extremely specific. – Ace Ebert Mar 30 '15 at 18:54
  • Have you tried looking at the plethora of similar question? Try this search: [stackoverflow c++ read file parameters](https://www.google.com/search?q=stackoverflow+read+from+file+parameters&ie=utf-8&oe=utf-8) – Thomas Matthews Mar 30 '15 at 18:58
  • Of course, I've got some Q&A at hand, that might give you a grip what's necessary to do with the line. See [here](http://stackoverflow.com/questions/24504582/how-to-test-whether-stringstream-operator-has-parsed-a-bad-type-and-skip-it) and [here](http://stackoverflow.com/questions/23047052/why-does-reading-a-struct-record-fields-from-stdistream-fail-and-how-can-i-fi) please. Both samples use `std::getline()` and `std::istringstream`. – πάντα ῥεῖ Mar 30 '15 at 19:08

2 Answers2

0
int i = 0;
while (inputFile >> studentInfo)
{
    cout << "Student " << i << "'s info is " << studentInfo << endl;
    ++i;
}

Is this what you were asking?

Edited for OP's comment. OK: so you want the info presented to be an average. So it makes sense (if this is what you want) to store that average. You can replace that loop on qz with this code, to make that happen:

    double totalScore = 0.0;
    enum {NUM_QUIZZES = 5};

    //read in 5 quizzes and get the total score
    for (qz = 1; qz < 5; qz++)
    {
        cout << "Enter quiz score " << qz << " ";
        cin >> score;

        totalScore += score;
    }

    //print the average score to a file
    outputFile << " " << totalScore/NUM_QUIZZES << " ";
Topological Sort
  • 2,733
  • 2
  • 27
  • 54
  • Closer! Yes, this is doing what I need it to, however I need to figure out how to get it to display averages, not just the score. A sample output of that is students 1's info: (students id) students 2's info (1st quiz score) etc. – Ace Ebert Mar 30 '15 at 18:59
  • @AceEbert _"how to get it to display averages"_ You'll need to parse the values to build the average from one by one until line ending, and calculate the average for all of them. Then you display the result. – πάντα ῥεῖ Mar 30 '15 at 19:02
  • @WillBriggs No, that wasn't exactly what the OP's asking for, there's more than a single `score` to be read from the file format, where the average should be calculated from per student. – πάντα ῥεῖ Mar 30 '15 at 19:03
  • That is correct, there is more than one score, I've done things like that before, but never in this way. I've researched it a lot but nothing seems to work... – Ace Ebert Mar 30 '15 at 19:07
  • See above answer for an answer to the averaging question as well. – Topological Sort Apr 01 '15 at 19:46
0

I added the following code to your existing code, after the comment "Output Finished"

double studentInfo;
inputFile.open("quizav.txt");

int count = 0, numstudents = 0, numquizzes = 4;
double studentScores = 0, studentAvg = 0, totalAvg = 0;
cout << endl << "Class Statistics" << endl << endl;

while (inputFile >> studentInfo){
    if(count == 0){         //if count == 0, then studentInfo contains the ID
        ++numstudents;      //increment number of students
        cout << "Current Student ID: " << studentInfo << endl;     //output student ID
    }
    else{                   //else, studentInfo contains a quiz score
        studentScores += studentInfo;       //total up cur student quiz scores
    }
    ++count;        //increment counter to keep track of which data your're looking at
    if(count == numquizzes + 1){        //if counter = number of quizzes + 1 for student ID, current student is now complete
        studentAvg = studentScores / numquizzes;    //compute the average for student
        totalAvg += studentAvg;         //add average to total for later class avg calculation
        studentScores = 0;              //reset scores for next student
        cout << "     Student Average: " << studentAvg << endl;     //output current student average
        count = 0;      //reset counter
    }
}
totalAvg = totalAvg/numstudents;        //when all students are evaluated, calc total average
cout << endl << "Class Average: " << totalAvg << endl;
inputFile.close();
return 0;

This is a basic way to calculate averages. The code contains comments explaining how it works.

It holds data of one student at a time, computing the average when all of the students data is read, moving on until all students are accounted for.

This is the output for my specified input:

Class Statistics

Current Student ID: 123
     Student Average: 5
Current Student ID: 234
     Student Average: 4.25
Current Student ID: 568
     Student Average: 4

Class Average: 4.41667
Happy Hippo
  • 102
  • 9