-3

I have this code:

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

void readStuData(ifstream& rss, int scores[],
                 int id[], int& count, bool& tooMany);

float mean(int scores[], int count);

void printTable(int score[], int ID[], int count);

void printGrade(int oneScore, float average);

int main() {
    const int MAX_SIZE = 10;
    ifstream rss;
    int numStuds = 0;
    int studScores[MAX_SIZE];
    int studIDs[MAX_SIZE];
    bool tooMany = false;
    int oneScore;
    float average;

    readStuData(rss, studScores, studIDs, numStuds, tooMany);

    printTable(studScores, studIDs, numStuds);

    for (int i = 0; i < MAX_SIZE; ++i) {
        oneScore = studScores[i];
    }
    average = mean(studScores, numStuds);
    printGrade(oneScore, average);

    return 0;
}

void readStuData(ifstream& rss, int scores[],
                 int id[], int& count, bool& tooMany) {
    int studScore;
    int studID;

    rss.open("StudentScores.txt");
    if (!rss.is_open()) {
        cout << "ERROR: Could not open file." << endl;
    }

    tooMany = false;
    count = 0;
    
    for (int i = 0; (i < 10) && (!tooMany) && (!rss.eof()); ++i) {
        rss >> studID;
        id[i] = studID;
        rss >> studScore;
        scores[i] = studScore;
        ++count;
    }

    if (count > 10) {
        tooMany = true;
    }

    if (tooMany) {
        cout << "ERROR: Too many inputs from file." << endl;
    }

    rss.close();
}

float mean(int scores[], int count) {
    float sum = 0.0;
    int i;

    for (i = 0; i < count; ++i) {
        sum += scores[i];
    }

    return sum / count;
}

void printGrade(int oneScore, float average) {
    if (oneScore > (average + 10)) {
        cout << setw(15) << left << "Outstanding" << endl;
    }
    else if ((oneScore > (average - 10)) && (oneScore < (average + 10))) {
        cout << setw(15) << left << "Satisfactory" << endl;
    }
    else if (oneScore < (average - 10)) {
        cout << setw(15) << left << "Unsatisfactory" << endl;
    }
}

void printTable(int score[], int ID[], int count) {
    cout << "Student ID" << '|';
    cout << setw(5) << "Score" << '|';
    cout << setw(10) << "Grade" << endl;
    cout << setfill('-') << setw(33) << "" << endl;
    cout << setfill(' ');

    for (int i = 0; i < count; ++i) {
        cout << setw(10) << left << ID[i] << '|';
        cout << setw(5) << left << score[i] << '|';
        printGrade(score[i], mean(score, count));
    }
}

Here is the output:

Student ID|Score|     Grade
---------------------------------
68194805  |73   |Satisfactory
45991296  |80   |Satisfactory
32948569  |82   |Satisfactory
22399466  |93   |Outstanding
97139677  |70   |Satisfactory
83812257  |77   |Satisfactory
30544477  |89   |Outstanding
97859404  |43   |Unsatisfactory
40787045  |71   |Satisfactory
73234827  |95   |Outstanding
Oustanding

The point of this program is to read student IDs and scores from a text file, take the average of all the scores, use the average to determine whether the score deserves an "Outstanding" grade, an "Unsatisfactory" grade, or a "Satisfactory" grade, and organize them into a three-column table. I have accomplished this except for the last "Outstanding" at the bottom, which is a repeat of the row above. This is the only issue I have and I cannot figure out why it's doing this. The "Outstanding" at the very bottom won't go away even when I deleted a part of the for loop.

Edit: I don't know how to make it all into plain text while still keeping the formatting readable.

M.Abdullah Iqbal
  • 219
  • 1
  • 17
  • All questions here should have all relevant information ***in the question itself as plain text***. Links can stop working at any time making questions meaningless. Code, data, or errors shown as images cannot be copy/pasted; or edited or compiled for further research and investigation. Can you [edit] this question, removing and replacing all links and images with all relevant information as plain text? All code must meet all requirements of a [mre]. You can find many other questions here that explain everything in plain text, please use them as an example for how your question should look. – Sam Varshavchik Nov 07 '21 at 23:25
  • Have you tried running your code line by line in a debugger while monitoring the values of all variables, in order to determine at which point your program stops behaving as intended? If you did not try this, then you may want to read this: [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/12149471) You may also want to read this: [How to debug small programs?](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Andreas Wenzel Nov 07 '21 at 23:48
  • 1
    `"I have asked another question but it got closed when it shouldn't have"` -- I disagree. Your previous question was closed with a reference to [another "duplicate" question](https://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop-condition-i-e-while-stream-eof-cons). This duplicate question addresses the bug you have with `rss.eof()` and the anwers to that question explain why it is wrong. Yet you do not seem to address any of the information contained in those answers in your new question. – Andreas Wenzel Nov 07 '21 at 23:56
  • You failed to describe "the only issue"*. Since you did not say what your code is supposed to do, I see no conflict between your output and what you said your code is supposed to do. Apparently, a second issue (described as "also", implying that it is independent of your "only" issue?) is that it should not show "Outstanding", but that is an easy fix. Just comment out the line `cout << setw(15) << left << "Outstanding" << endl;` and that output will disappear and not conflict with any of your stated goals. – JaMiT Nov 08 '21 at 00:20
  • [Code samples](https://stackoverflow.com/help/mcve) should be *minimal*, complete and representative. – outis Nov 10 '21 at 09:21
  • Question quality is better, but still poor due to [extraneous code](//idownvotedbecau.se/toomuchcode/). – outis Dec 25 '21 at 03:36

2 Answers2

1

You should never start processing input before verifying beforehand that reading the input was successful.

In particular, you should not execute any of the lines

id[i] = studID;

and

scores[i] = studScore;

and

++count;

without verifying beforehand that the statements

rss >> studID;

and

rss >> studScore;

were successful, i.e. that the failbit was not set.

Your solution of using rss.eof() in the loop condition is not helpful, for the reasons stated in this question:

Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?

I suggest that you change the lines

for (int i = 0; (i < 10) && (!tooMany) && (!rss.eof()); ++i) {
    rss >> studID;
    id[i] = studID;
    rss >> studScore;
    scores[i] = studScore;
    ++count;
}

to:

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

    //attempt to read and convert input
    rss >> studID;
    rss >> studScore;

    //break loop prematurely on failure (e.g. due to EOF)
    if ( !rss )
        break;

    //input was ok, so now we can process the input
    id[i] = studID;
    scores[i] = studScore;
    ++count;
}

Also, it is worth mentioning that your following code is redundant:

if (count > 10) {
    tooMany = true;
}

if (tooMany) {
    cout << "ERROR: Too many inputs from file." << endl;
}

Since the previous loop limits count to 10, it will never be larger than 10, so tooMany = true will never be executed, which means that the following if statement will also never be executed.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39
1

"Outstanding" is printed by printGrade, so if there's an extra, undesired "Outstanding" in the output, look to where printGrade is called, directly or indirectly.

printGrade is called in two places: printTable and main. This by itself is enough to identify why there's an additional "Outstanding" after the table: it's explicitly (and thus presumably purposefully) produced by the program. If you don't want it, remove the call to printGrade in main.

This case would have benefited from one of the great advantages of minimal, complete sample code: it reduces noise, making the problem more apparent to you (as well as those you ask). Oftentimes, you won't need to ask for help after creating a minimal sample.

Another thing that could have revealed the issue is an interactive debugger. If you're going to spend any time programming, it's imperative to learn how to use them.

outis
  • 75,655
  • 22
  • 151
  • 221