Will Estes
Will Estes

Reputation: 75

C++ : User Input of Names and Scores, unknown number of names, compare scores

I need some help with homework. I need to create a program that gets names from the user, then asks for 5 scores for those names. There is an unknown number of names being entered. After the user finishes entering each name and scores, the program needs to calculate the average score after dropping the high and low scores. For example, the user enters "Nick" w/scores 8,7,6,5,4. Scores 8 and 4 would be dropped, and the average would be calculated off of 5,6,7. My questions are: How do I connect the input names with their corresponding scores? How do I fix this error "Stack around the variable 'scoreArray' was corrupted?" Below is the code I have so far.

#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

double calcAvgScore(int, int, int, int, int);
int checkValid(int);
int findLowest(int, int, int, int, int);
int findHighest(int, int, int, int, int);

int main() {

    string contestant;
    int score, i, arrayPos = 0;
    int scoreArray[5] = {};
    double avgScore;

    cout << "Enter the name of the star. Enter Done if no more stars.\n";
    cin >> contestant;
    while (contestant != "Done" && contestant != "done")
    {
        for  (i = 1; i < 6; i++)
        {
            cout << "Enter judge " << i << " score: ";
            cin >> score;
            checkValid(score);
            scoreArray[arrayPos] = score;
            ++arrayPos;
        }

        avgScore = calcAvgScore(scoreArray[0], scoreArray[1], scoreArray[2],
                                scoreArray[3], scoreArray[4]);
        cout << "Average Score " << setprecision(2) << fixed << avgScore << endl;
        cout << endl;
        cout << "Enter the name of the star. Enter Done if no more stars.\n";
        cin >> contestant;
    }


    system("pause");
    return 0;
}

double calcAvgScore(int score1, int score2, int score3, int score4,
                    int score5) {
    int low, high, totalScore;
    low = findLowest(score1, score2, score3, score4, score5);
    high = findHighest(score1, score2, score3, score4, score5);
    totalScore = score1 + score2 + score3 + score4 + score5 - low - high;
    double avgScore = double(totalScore) / 3;
    return avgScore;
}

int checkValid(int score) {
    while (score < 1 || score > 10)
    {
        cout << "Please enter a valid score: ";
        cin >> score;
    }
    return score;
}

int findLowest(int score1, int score2, int score3, int score4, int score5) {
    int low = 11;
    int array[5] = { score1, score2, score3, score4, score5 };
    for (int i = 0; i < 5; i++)
    {
        if (array[i] < low)
        {
            low = array[i];
        }
    }
    return low;
}

int findHighest(int score1, int score2, int score3, int score4, int score5) {
    int high = 0;
    int array[5] = { score1, score2, score3, score4, score5 };
    for (int i = 0; i < 5; i++)
    {
        if (array[i] > high)
        {
            high = array[i];
        }
    }
    return high;
}

corrected code:

#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <algorithm>

using namespace std;

double calcAvgScore(int, int, int, int, int);
int checkValid(int);
int findLowest(int, int, int, int, int);
int findHighest(int, int, int, int, int);

int main() {

    string contestant;
    int score, i, y, arrayPos;
    int scoreArray[5] = {};
    vector<string> names{};
    double avgScore, maxAvg;
    vector<double> avgScoreVec{};

    cout << "Enter the name of the star. Enter Done if no more stars.\n";
    cin >> contestant;
    while (contestant != "Done" && contestant != "done")
    {
        names.push_back(contestant);
        arrayPos = 0;
        for  (i = 1; i < 6; i++)
        {
            cout << "Enter judge " << i << " score: ";
            cin >> score;
            score = checkValid(score);
            scoreArray[arrayPos] = score;
            ++arrayPos;
        }
        avgScore = calcAvgScore(scoreArray[0], scoreArray[1], scoreArray[2],
        scoreArray[3], scoreArray[4]);
        avgScoreVec.push_back(avgScore);
        cout << endl;
        cout << "Enter the name of the star. Enter Done if no more stars.\n";
        cin >> contestant;
    }

    maxAvg = *max_element(avgScoreVec.begin(), avgScoreVec.end());
    y = find(avgScoreVec.begin(), avgScoreVec.end(), maxAvg) - avgScoreVec.begin();
    cout << "... and the winner is " << names[y] << " with a score of " << 
    setprecision(2) << fixed << maxAvg << endl;

    system("pause");
    return 0;
}

double calcAvgScore(int score1, int score2, int score3, int score4, 
                int score5) {
    int low, high, totalScore;
    low = findLowest(score1, score2, score3, score4, score5);
    high = findHighest(score1, score2, score3, score4, score5);
    totalScore = score1 + score2 + score3 + score4 + score5 - low - high;
    double avgScore = double(totalScore) / 3;
    return avgScore;
}

int checkValid(int score) {
    while (score < 1 || score > 10)
    {
        cout << "Please enter a valid score: ";
        cin >> score;
    }
    return score;
}

int findLowest(int score1, int score2, int score3, int score4, int score5) {
    int low = 11;
    int array[5] = { score1, score2, score3, score4, score5 };
    for (int i = 0; i < 5; i++)
    {
        if (array[i] < low) 
        {
            low = array[i];
        }
    }
    return low;
}

int findHighest(int score1, int score2, int score3, int score4, int score5) {
    int high = 0;
    int array[5] = { score1, score2, score3, score4, score5 };
    for (int i = 0; i < 5; i++)
    {
        if (array[i] > high)
        {
            high = array[i];
        }
    }
    return high;
}

Upvotes: 0

Views: 2348

Answers (2)

vsoftco
vsoftco

Reputation: 56567

You should learn using a debugger and step through your code, so you understand what is happening. The loop

while (contestant != "Done" && contestant != "done")
{
    for  (i = 1; i < 6; i++)
    {
        cout << "Enter judge " << i << " score: ";
        cin >> score;
        checkValid(score);
        scoreArray[arrayPos] = score;
        ++arrayPos;
    }
    // ....

is dubious. First, if you don't type "done" or "Done", you keep incrementing arrayPos, and its value becomes larger than 4, so you end up accessing out of bounds. Second, checkValid(score); should be score = checkValid(score);, as otherwise score remains unchanged (it is local to the function checkValid()). If you want a resizable array, consider using std::vector instead. Consider also using a std::map instead.

Upvotes: 1

syntagma
syntagma

Reputation: 24344

How do I connect the input names with their corresponding scores?

You can use std::map<string, double> to map from name to input score (if average score is what you want to map into).

How do I fix this error "Stack around the variable 'scoreArray' was corrupted?"

You should zero your arrayPos variable, at this point:

arrayPos = 0;
for (i = 1; i < 6; i++) {
    // ...
}

Right now the arrayPos variable can easily go out of bounds (i.e. become > 4) and you will write onto the stack (i.e. where scoreArray has been allocated) though you are not allowed to.

Upvotes: 1

Related Questions