-1

I have to write a code, where a user enters a number of students and their surnames (then they will get 5 different grades). Their averages have to be calculated and displayed. Next, the overall average (of the students' averages) has to be calculated. I've been trying to get it but I always get weird numers... Could anyone have a look at it and help me? And I've got another question. What should I do to enter a surname and get the person's data displayed?

#include <iostream>
#include <iomanip>

using namespace std;

struct STUDENT
{
  string surname;
  double grades[5];
  double average;
};


void random(STUDENT &a);
void display(STUDENT a);

void random(STUDENT &a){
srand(time(NULL));
    cin >> a.surname;
    for(int i = 0; i < 5; i++) {
        for (int i = 0; i < 5; ++i) {
            double locen[7]={2, 2.5, 3, 3.5, 4, 4.5, 5};
            int wyboc = rand()%(7);
            a.grades[i] = locen[wyboc];
        }
    }
}

void display(STUDENT a){
double sum = 0;
cout << a.surname << endl;

    for(int i=0; i <5; i++){
        cout<< "Grades " << i + 1 << ": " << setprecision(2) << a.grades[i] << endl;
            sum += a.grades[i];
            a.average = sum/5;
    }
    cout << "Average is: " << a.average;

 }
double average(STUDENT a, int numberOfStudents){
    double sum = 0;
    double sumAverage = 0;
    for (int i = 0; i < numberOfStudents; i++){
            sum += a.grades[i];
        }
    sumAverage = a.average / numberOfStudents;
    cout << "All students' average: " << sumAverage << endl;
}


int main(){
    int numberOfStudents;

    cout << "Enter number of students: ";
    cin >> numberOfStudents;

    if (numberOfStudents <= 0){
        cout << "You cannot enter 0" << endl;
        return -1;
    }

    STUDENT tab[numberOfStudents];

    for (int i = 0; i < numberOfStudents; i++){
        cout << "Enter surname " << (i + 1) << ": ";
        random(tab[i]);
    }
    for(int i=0;i<numberOfStudents;i++){
        cout<<"\nStudent "<<i+1<<": ";
        display(tab[i]);
    }

    average(a, numberOfStudents);

}
  • You are using random numbers that change each time you run the program -- could this be why they are weird? – tobias Jun 13 '21 at 15:39
  • `STUDENT` being all caps will confuse people who think it's a macro. `Student` would be much better. You initialize your prng in the `random()` function; this is bad. Your prng should be initialized only once, and you should prefer `` prngs over `rand`. – sweenish Jun 13 '21 at 15:41
  • 2
    This program doesn't compile (let alone run or produce results, weird or otherwise). Undeclared identifier `a` in `average(a, numberOfStudents);` – Igor Tandetnik Jun 13 '21 at 16:34

1 Answers1

0

Your program does not compile. You did not define 'a' in 'average(a, numberOfStudents);' and a stack-allocated array has to have a size that is known at compile time. Therefore 'STUDENT tab[numberOfStudents];' won't work because numberOfStudents is not known at compile time. The following code addresses these problems and calculates the average of the average grades of each student:

#define GRADES_PER_STUDENT 5

struct Student {
    std::string name;
    std::array<double, GRADES_PER_STUDENT> grades;
    double averageGrade;
};

std::size_t getNumStudents() {

    std::size_t numStudents;
    std::cout << "number of students: ";
    std::cin >> numStudents;
    std::cout << "\n";

    return numStudents;
}

std::string getStudentName() {

    std::string name;

    std::cout << "new Student: \n";
    std::cout << "    name: ";
    std::cin >> name;
    std::cout << "\n";

    return name;
}

std::array<double, GRADES_PER_STUDENT> getStudentGrades() {

    std::array<double, GRADES_PER_STUDENT> grades;

    for (int i = 0; i < grades.size(); i++)
        grades[i] = std::rand() % 7;

    return grades;
}

double getAverageGrade(const std::array<double, GRADES_PER_STUDENT>& grades) {
    double sumOfGrades = std::accumulate(grades.begin(), grades.end(), 0.0);
    return sumOfGrades / GRADES_PER_STUDENT;
}

Student getRandomStudent() {

    Student student;

    student.name = getStudentName();
    student.grades = getStudentGrades();
    student.averageGrade = getAverageGrade(student.grades);

    return student;
}

double getAverageGrade(const std::vector<Student>& students) {

    double sumOfGrades = std::accumulate(students.begin(), students.end(), 0.0, 
        [&](double sum, const Student& student) { return sum + student.averageGrade; }
    );
    return sumOfGrades / students.size();
}

int main() {

    std::srand(std::time(NULL));

    std::size_t numStudents = getNumStudents();

    std::vector<Student> students;
    for (int i = 0; i < numStudents; i++)
        students.push_back(getRandomStudent());

    double avarageGrade = getAverageGrade(students);

    std::cout << "avarage grade of all students: " << avarageGrade << "\n";

    return 0;
}

As already mentioned your naming convention is confusing. It is also bad practice to use 'using namespace std' (see: Why is "using namespace std;" considered bad practice?). Why std::rand is considered bad see: Why is the use of rand() considered bad?.

Sebphil
  • 488
  • 5
  • 12