I'm getting one error in my code

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;
}
The constructor expects the second argument to be of type gender but you're passing an int.
Last edited on
Line 63: Pass _g instead of c. The compiler is basically complaining about the wrong type passed to the constructor.
L63 - replace c with _g
L62 - note the first assignment to _g isn't needed as the if statement has an else
@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
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
but how do I return a vector of classes, do I do each member individually?

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
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.
but how do I return a vector of classes?
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
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
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
.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; }

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.