I'm getting one error in my code

Mar 1, 2022 at 9:23am
In the ReadStudents function for "Student Student { _id, c, _fname, _lname, _cname, _Icount };" I'm getting an error for the curly brackets.

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  #include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

enum class gender {
    Male, Female
};

class Student {
private:
    string id, fname, lname, cname;
    int Icount;
    gender g;
public:
    Student() { fname = "None"; lname = "None"; id = "None"; cname = "None"; Icount = 0; g = gender::Female; }
    Student(string _id, gender _g, string _fname, string _lname, string _cname, int _Icount) {
        fname = _fname;
        lname = _lname;
        id = _id;
        cname = _cname;
        Icount = _Icount;
        g = _g;
    }
    void setfname(string _fname) { fname = _fname; } string getfname() {
        return fname;
    }
    void setlname(string _lname) { fname = _lname; } string getlname() {
        return lname;
    } void setid(string _id) { fname = _id; } string getid() {
        return id;
    } void setcname(string _cname) { fname = _cname; } string getcname() {
        return cname;
    }
    void setIcount(int _Icount) { Icount = _Icount; } int getIcount() {
        return Icount;
    }
    void setg(gender _g) { g = _g; } gender getg() {
        return g;
    }
    void print() {
        int c;
        if (c == 1) cout << "Female"; else cout << "Male";
        cout << "ID [" << id << "] First Name [" << fname << "] Last Name [" << lname << "] Gender [" << c << "] Course [" << cname << "] Attendance [" << Icount << "]\n";
    }
};

vector<Student> readStudents(string filename) {
    int size;
    string temp;
    vector <Student> students;
    ifstream f;
    f.open("Text.txt");
    if (f.fail()) {
        cout << "Failed to open file"; exit(1);
    }
    f >> size; getline(f, temp); getline(f, temp);
    for (int i = 0; i < size; i++) {
        int c; string _fname, _lname, _id, _cname; gender _g; int _Icount;
        f >> _id >> c >> _fname >> _lname >> _cname >> _Icount;
        _g = gender::Female; if (c == 0)_g = gender::Male; else _g = gender::Female;
        Student Student { _id, c, _fname, _lname, _cname, _Icount };
        students.push_back(Student);
    }
    return students;
}
void printStudents(vector<Student> stds)
{
    string c;
    for (int i = 0; i < stds.size(); i++) {
        if (stds[i].getg() == gender::Female) c = "Female";  
        else c = "Male";
        cout << "ID [" << stds[i].getid() << "] First Name [" << stds[i].getfname() << "] Last Name [" << stds[i].getlname() << "] Gender [" << c << "] Course [" << stds[i].getcname() << "] Attendance [" << stds[i].getIcount() << "]\n";
        
    }
}

vector<Student> getFemales(const vector<Student>& stds) {
    int i = 0;
    vector <Student> stf = stds;
    while (stf[i].getg()== gender::Female)
        {
        printStudents(stf); i++;
        }
}

vector<Student> getLowAttendance(const vector<Student>& stds) {
    int i = 0;
    vector <Student> stl = stds;
    while (stl[i].getIcount() < 20) {
        printStudents(stl); i++;
    }
}


int main()
{

    vector <Student> stds_vect;
    string file;
    stds_vect = readStudents(file);
    for (int i = 0; i < stds_vect.size(); i++) {
        printStudents(stds_vect);
    }
    getFemales(stds_vect);
    getLowAttendance(stds_vect);


    return 0;
}
Mar 1, 2022 at 9:29am
The constructor expects the second argument to be of type gender but you're passing an int.
Last edited on Mar 1, 2022 at 9:33am
Mar 1, 2022 at 9:31am
Line 63: Pass _g instead of c. The compiler is basically complaining about the wrong type passed to the constructor.
Mar 1, 2022 at 9:33am
L63 - replace c with _g
L62 - note the first assignment to _g isn't needed as the if statement has an else
Mar 1, 2022 at 9:36am
@Peter87 thanks for pointing that out. One more thing, for the getFemales and getLowAttendance functions, it asks to return a value while I'm already using the print function. What should I return then without changing the void type?
Last edited on Mar 1, 2022 at 9:37am
Mar 1, 2022 at 9:40am
Printing is not the same as returning. Functions named "get" should normally not print anything at all. Instead use the return keyword to return what it is you want to return, like you did with the "get" member functions of the Student class.
Last edited on Mar 1, 2022 at 9:42am
Mar 1, 2022 at 9:44am
but how do I return a vector of classes, do I do each member individually?

Mar 1, 2022 at 9:48am
No you just return the whole vector.

1
2
3
4
5
std::vector<int> getNumbers()
{
	std::vector<int> nums = {1, 2, 3};
	return nums;
}
Last edited on Mar 1, 2022 at 9:48am
Mar 1, 2022 at 9:49am
I'd suggest having an additional function eg displayStudent(const Student& s) to display the details of the passed student. This can then be used by the 3 current functions that show student details.

You need to decide what the functions getFemales() and getLowAttendence() are supposed to do. Do they find the appropriate students and display their details - or find the appropriate students and return a vector of them? If return a vector then main() will need to display them. get functions usually return something and print/display functions generally don't.
Mar 1, 2022 at 10:01am
but how do I return a vector of classes?
Mar 1, 2022 at 10:01am
Yes - but that prints all students. if getLowAttendence() etc is to display the students (as opposed to return them) then:

1
2
3
4
5
void getLowAttendance(const vector<Student>& stds) {
    for (int i = 0; i < stds.size(); ++i)
        if (stds[i].getIcount() < 20)
            displayStudent(stds[i]);
}


However, if getxxx return a vector, then something like (not tried):
1
2
3
4
5
6
7
8
9
10
11
12
13
vector<Student> getLowAttendance(const vector<Student>& stds) {
    vector <Student> stl;

    for (int i = 0; i < stds.size(); ++i)
        if (stds[i].getIcount() < 20)
            stl.push_back(stds[i]);

    return stl;
}
...
//in main

    printStudents(getLowAttendance(stds_vector));


In this case then yes, displayStudent() isn't needed.

PS The previous post referred to has now been removed.

PPS printStudents should pass by const reference

 
void printStudents(const vector<Student>& stds)


NOTE. I've now realised that the class Student has a member function print() which does what my displayStudent() would do - so print() should be used instead.
Last edited on Mar 1, 2022 at 10:49am
Mar 1, 2022 at 10:08am
if (stds[i].getIcount() < 20)

error in stds for some reason. I like your idea though, I remember doing something similar for a previous exercise
Mar 1, 2022 at 10:09am
but how do I return a vector of classes?

There is no difference. Just make sure the vector contains the objects that you want to return and return it.

PS The previous post referred to has now been removed.

I'm sorry. I realized my mistake and removed it soon after posting it.

PPS printStudents should pass by const reference

The main reason for this is to avoid creating unnecessary copies which can be slow if the vector contains many elements. You might want to do the same with the std::string parameters for the same reason.
Last edited on Mar 1, 2022 at 10:28am
Mar 1, 2022 at 10:12am
.getIcount() needs to be defined as const in the class defrinition- as stds is now const.

All the class getxxx functions should be defined as const

 
int getIcount() const { return Icount; }

Mar 1, 2022 at 10:47am
There are various other issues with the code. Consider this, but not tested as no test data provided:

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;

enum class gender { Male, Female };

class Student {
private:
	string id{"None"}, fname {"None"}, lname{"None"}, cname{"None"};
	int Icount {};
	gender g {gender::Female};

public:
	Student() { }
	Student(const string& _id, gender _g, const string& _fname, const string& _lname, const string& _cname, int _Icount) :
		fname(_fname), lname(_lname), id(_id), cname(_cname), Icount(_Icount), g(_g) {}

	void setfname(const string& _fname) { fname = _fname; }
	string getfname() const {return fname; }
	void setlname(const string& _lname) { lname = _lname; }
	string getlname() const { return lname;	}
	void setid(const string& _id) { id = _id; }
	string getid() const { return id; }
	void setcname(const string& _cname) { cname = _cname; }
	string getcname() const { return cname; }
	void setIcount(int _Icount) { Icount = _Icount; }
	int getIcount() const { return Icount; }
	void setg(gender _g) { g = _g; }
	gender getg() const { return g; }

	void print() const {
		cout << "ID [" << id << "] First Name [" << fname << "] Last Name [" << lname << "] Gender [";

		if (g == gender::Female)
			cout << "Female";
		else
			cout << "Male";

		cout << "] Course [" << cname << "] Attendance [" << Icount << "]\n";
	}
};

vector<Student> readStudents(const string& filename) {
	ifstream f(filename);

	if (!f) {
		cout << "Failed to open file";
		exit(1);
	}

	int size {};
	string temp;
	vector <Student> students;

	f >> size;
	getline(f, temp);
	getline(f, temp);

	for (int i = 0; i < size; i++) {
		int c {};
		string _fname, _lname, _id, _cname;
		int _Icount {};

		if (f >> _id >> c >> _fname >> _lname >> _cname >> _Icount) {
			gender _g {c == 0 ? gender::Male : gender::Female};

			students.emplace_back(_id, _g, _fname, _lname, _cname, _Icount);
		}
	}

	return students;
}

void printStudents(const vector<Student>& stds) {
	for (int i = 0; i < stds.size(); i++)
		stds[i].print();
}

vector<Student> getFemales(const vector<Student>& stds) {
	vector<Student> stf;

	for (int i = 0; i < stds.size(); ++i)
		if (stds[i].getg() == gender::Female)
			stf.push_back(stds[i]);

	return stf;
}

vector<Student> getLowAttendance(const vector<Student>& stds) {
	vector<Student> stl;

	for (int i = 0; i < stds.size(); ++i)
		if (stds[i].getIcount() < 20)
			stl.push_back(stds[i]);

	return stl;
}

int main() {
	const auto stds_vect {readStudents("text.txt")};

	printStudents(stds_vect);
	printStudents(getFemales(stds_vect));
	printStudents(getLowAttendance(stds_vect));
}

Topic archived. No new replies allowed.