Loops and File Structures Help

I'm stuck on a couple parts of this including saving all of the information to the output file and how to determine the winner. Any help is appreciated

There are five judges who will each give a score between 4 and 10 to each performer. These scores should be generated using the random number generator.
The program will ask (using cout, cin) for the number of performers. A for loop should be used in the main program to process this number of performers.
A function CalculateScore should display the five scores for each performer. It should calculate and display the average of the three scores that remain after the highest and lowest scores are dropped for the performer. This function should be called by main for each performer and passed the five scores for the performer. Additional functions can be used if needed.
After all performers have been given their average, the winner (person with highest score) should be announced.
Sample output might look like:
There are 3 performers.
Scores for Performer1 are: 8, 6, 6, 7, 10
The average of the three scores used is: 7.0
Scores for Performer2 are: 5, 9, 8, 8, 10
The average of the three scores used is: 8.3
Scores for Performer3 are: 5, 4, 7, 5, 8
The average of the three scores used is: 5.7
The winner is Performer2 with a high score of: 8.3

The output should be sent to two places. It should go to the screen (using cout) and it should be sent to an output file.

This is what I have so far:


#include<iostream>
#include<cstdlib>
#include<ctime>
#include<iomanip>
#include<fstream>

using namespace std;

void CalculateScore(int score1, int score2, int score3, int score4, int score5)
{
static int performers = 1;
double avgScore, TotalScore;
int LowNum = 10;
int HighNum = 4;

if (LowNum > score1)
LowNum = score1;
else if (LowNum > score2)
LowNum = score2;
else if (LowNum > score3)
LowNum = score3;
else if (LowNum > score4)
LowNum = score4;
else if (LowNum > score5)
LowNum = score5;

if (HighNum < score1)
HighNum = score1;
else if (HighNum < score2)
HighNum = score2;
else if (HighNum < score3)
HighNum = score3;
else if (HighNum < score4)
HighNum = score4;
else if (HighNum < score5)
HighNum = score5;

TotalScore = (score1 + score2 + score3 + score4 + score5) - LowNum - HighNum;
avgScore = TotalScore / 3.0;

cout << "Scores for Performer " << performers << " are " << score1 << ", " << score2 << ", " << score3 << ", " << score4 << ", " << score5 << endl;
performers++;
cout << setprecision(1) << fixed;
cout << " The average of their 3 scores are " << avgScore <<endl;

ofstream outputFile;
outputFile.open("lastname.txt");
outputFile << score1 << " " << score2 << " " << score3 << " " << score4 << " " << score5 << endl;
outputFile << avgScore << endl;
outputFile.close();

}

int main()
{
const int minValue = 4;
const int maxValue = 10;
int score1, score2, score3, score4, score5;
int NumPerformers;

unsigned seed = time(0);
srand(seed);

cout << "Enter the # of performers" << endl;
cin >> NumPerformers;

for (int count = 1; count <= NumPerformers ;count++)
{
score1 = (rand() % (maxValue - minValue + 1)) + minValue;
score2 = (rand() % (maxValue - minValue + 1)) + minValue;
score3 = (rand() % (maxValue - minValue + 1)) + minValue;
score4 = (rand() % (maxValue - minValue + 1)) + minValue;
score5 = (rand() % (maxValue - minValue + 1)) + minValue;

CalculateScore(score1, score2, score3, score4, score5);
}
}
Hello OP: I have got 2 programs for you – one that doesn't work and one that, hopefully, does.
Let's do the working one first and then I'll leave a few remarks about the non-working one in case you or anyone else is interested:
For the working program I used std::list to generate 5*n random numbers b/w 4 and 10, where 5 is the # of judges and n is the # of performers (there's a story behind doing this all at once that'll become clearer when we get to the program that doesn't work!)
To extract the scores for each performer we then splice the list into as many sublists as there are performers (this is the primary motivation behind using std::list, though given the advances in std::vector technology wiith move semantics maybe using std::vector would also not impose any performance penalty. I have a working version with std::vector as well, let me know if interested in seeing it).
Then we sort the sublists, remove min and max scores, take average and print to console and file – this bit is more-or-less straightforward. There are further comments and links within the program below:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

#include <iostream>
#include <vector>
#include <algorithm>
#include <chrono>
#include <random>
#include <iomanip>
#include <fstream>

constexpr auto low_score = 4;
constexpr auto high_score = 10;
constexpr auto numJudges = 5;

std::vector<double> getScore( const size_t performers)
{
    auto seed = std::chrono::system_clock::now().time_since_epoch().count();//seed
    std::default_random_engine dre(seed);//engine
    std::uniform_int_distribution<int> di(low_score,high_score);//distribution based on low and hi scores

    std::vector<int> scores(numJudges * performers);//to record the scores
    std::generate(scores.begin(), scores.end(), [&]{ return di(dre);});
    //generates 5 random nos b/w 4 and 10 for each performer

    std::vector<double> avg_scores{};//container to store the average scores;

    auto start_itr = scores.begin();
    auto end_itr = start_itr + numJudges;
    for (size_t i = 0; i < performers; ++i)
    {
        std::vector<int> tempScores {start_itr, end_itr};//each performers scores from 5 judges
        std::sort(tempScores.begin(), tempScores.end());//sort each performers scores
        std::vector<int> truncated_scores {&tempScores[1], &tempScores[tempScores.size()-1]};
        //truncate the highest and lowest scores
        avg_scores.push_back(static_cast<double>(std::accumulate(truncated_scores.begin(), truncated_scores.end(),0))/3);
        //average the truncated scores and store them in the vector avg_scores;
        start_itr += numJudges;//now advance both iterators by numJudges;
        end_itr += numJudges;
    }
    return avg_scores;
}

int main()
{
    std::ofstream outFile {"D:\\test.txt"};
    auto avg_scores = getScore(3);
    std::cout << "Averages of the performers: \n";
    for (const auto& elem : avg_scores)
    {
        std::cout << std::setprecision(3) << elem << "\n";
        outFile << std:: setprecision(3) << elem << "\n";
    }
}


Now let's come to the more interesting bit – viz. the program that doesn't work – here instead of generating all the 5*n random numbers at once (5 judges, n performers) I thought I'd call the getScore() method n times and, lo and behold, try as I might, it keeps giving me the same output for all the performers. I've tried seeding the random engine in endless different ways but to no avail. The below link is to a program that seeds only once but still manages to end up with the same scores for each performer. If anybody has any light to shed on this it'd be received gratefully, thank you:
https://pastebin.com/kfNuAjC9


Hello Jopma,

PLEASE ALWAYS USE CODE TAGS (the <> formatting button) when posting code.
It makes it easier to read your code and also easier to respond to your post.
http://www.cplusplus.com/articles/jEywvCM9/
http://www.cplusplus.com/articles/z13hAqkS/
Hint: You can edit your post, highlight your code and press the <> formatting button.
You can use the preview button at the bottom to see how it looks.

The only part I that is missing is keeping tack of who won. And the line outputFile.open("lastname.txt");. Since you open and close the output file in the function the line would be better written as: outputFile.open("lastname.txt", std::ios::app);. A different way would be to open and close the output file in main and pass the file stream handle to any functions that need it. I would pass by reference. Opening the output file for append in the function would always add to the file.

I do not know if order makes any difference, but I tend to write this line this way:

1
2
3
std::cout << std::fixed <<std::showpoint << std::setprecision(2);  // <--- You had as 1, instructions says 2.


Hope that helps,

Andy
Topic archived. No new replies allowed.