0

I created a class with students and groups. The group consists of the group name and the number of students. The student class consists of: student name, price, and logical operation scholarship. My main goal is to find the average of the grades received by students in their group. However, if a student's scholarship is - > false, then we don't count them. This is the main problem. I created both classes, combined them using a vector, wrote a program so that it would display the average scores of the groups, but when I turn on the program, the console only displays the name of the first group.

I want to clarify that this task is for a two-dimensional array. I just changed it to vectors to learn about the vectors (I don't know vectors well, but I will learn more about vectors in the future).

Here's my code:


#include <iostream>
#include <vector>
using namespace std;

class Student {
public:
    string name;
    double grade;
    bool Grant;
    Student() {
        string is_Grant;
        cin >> name >> grade >> is_Grant;
        if (is_Grant == "true") {
            Grant = true;
            } else
                Grant = false;
    }

    string GetName() {
        return name;
    }
    double Get_Grade() {
        return grade /** (Grant)*/;
    }
};

class Group {
public:
    string G_Name;
    int count;
    vector<Student> stud;

    Group() {
        cin >> G_Name >> count;
        vector<Student> stud(count);
    }

    double GetAverage()
    {
        cout << "\n";
        double avg = 0;
        for (int i = 0; i < count; i++)
        {
            avg += stud[i].Get_Grade();
        }
        return avg / stud.size();
    }

};

int main() {
    int size;
    cin >> size;

    vector<Group> grp(size);
    for (int i = 0; i < size; i++)
    {
        cout << grp[i].G_Name << ": Average is " << grp[i].GetAverage() << endl;
    }
}

I want to know where I made a mistake. Maybe I forgot to add something? First, I was using Void GetAvg() instead of a string. At that time, when I only typed in the number of inputs, the program stopped there. I also tried creating a bool value as a separate function, but it wouldn't output either. Most importantly, I want to know why the program doesn't find the average value.

Damir
  • 11
  • 2
  • 2
    [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems?r=Saves_AllUserSaves) – πάντα ῥεῖ Dec 10 '22 at 17:58
  • that is a very strange way to load your data. – pm100 Dec 10 '22 at 18:00
  • From your `main()` you're never inputted something to your `grp` vector, so what do you actually expect?? – πάντα ῥεῖ Dec 10 '22 at 18:00
  • 2
    In the `Group` constructor `vector stud(count);` creates a temporary variable that is immediately destroyed when the function ends. The `stud` member variable is unchanged. It's likely your program is waiting for input since both the `Group` and `Student` constructors require it. In general that's a poor design. Input should be separate so you can control the order and validate it. – Retired Ninja Dec 10 '22 at 18:01
  • you have 2 things called 'stud' in your group constructor – pm100 Dec 10 '22 at 18:04
  • Can you give me links to a sample solution so I can fix my code. – Damir Dec 10 '22 at 18:04
  • @Damir [we don't do that here, sorry](https://meta.stackoverflow.com/questions/274625/how-can-i-better-ask-this-question-about-finding-example-code-to-learn-from) – πάντα ῥεῖ Dec 10 '22 at 18:27
  • @Damir Do your input in `main`, create constructors with *parameters* which can be called with the values you input in `main`. – john Dec 10 '22 at 18:30

1 Answers1

1

So your code is super weird and I'm not sure it can ever work, but there is one obvious error

Group() {
    cin >> G_Name >> count;
    vector<Student> stud(count);
}

that should be

Group() {
    cin >> G_Name >> count;
    vector<Student> s(count);
    stud = s;
}

Your version creates a local variable called stud which is a vector with the given size, but that has nothing to do with the stud that is a member variable in the Group class. My version uses a different name and then assigns that variable to stud.

This is still weird code, the code I originally wrote in the answer was the more natural

Group() {
    cin >> G_Name >> count;
    vector<Student> s(count);
    stud.resize(count);
}

but this code doesn't work because your strange constructors. This version of the code only creates one Student which is then copied to fill in the vector. So you would end up with count identical students. More on this in the last paragraph.

The reason for your error is that when you call GetAverage you have some value for count but because of the bug the size of stud is still zero, so you are accessing that vector out of bounds and that (probably) is what is crashing your code.

And that brings up another issue with your code. One of the reasons vectors are superior to arrays is that vectors know their own size, and so variables like count are redundant, just query the vector for it's size. Rewriting your code to take advantage of that gives you something like this

class Group {
public:
    string G_Name;
    vector<Student> stud;
    // no count in group

and this

Group() {
    int count; // count is now a local variable
    cin >> G_Name >> count;
    vector<Student> s(count);
    stud = s;
}

and this

double GetAverage()
{
    cout << "\n";
    double avg = 0;
    for (int i = 0; i < stud.size(); i++) // get the count from the vector
    {
        avg += stud[i].Get_Grade();
    }
    return avg / stud.size();
}

But the elephant in the room is the way you do data input in your constructors. Don't do that. It means that every time you declare a variable the program is going to pause and ask the user for input. It also means that every student you do want to create has to be created with the default constructor, which is why my resize code doesn't work. Think about how restricting that is going to be going forward.

john
  • 85,011
  • 4
  • 57
  • 81