Error in code

Hello once again guys! I have one more problem regarding another code of mine. My code is given below and the problem is that when I run the code I does not print the names of the students. In addition, it does not print the part of the code which states how many vacancies in the team are there. Somewhere within this section of the code there is a problem but I can't spot it. COuld you please advice?

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
class date {
private:
    double imera{};
    double minas{};
    double etos{};
public:
    date(){};
    date(double i, double m, double e) : imera(i), minas(m), etos(e) {};
    void set_date(double i, double m, double e) { imera = i; minas = m; etos = e; };
    double get_date() { return imera; return minas; return etos; };
    void display() {
        cout << imera << '/' << minas << '/' << etos << endl;
    };
};

class ergasia {
private:
    string title{};
    double grade{};
    string names[5];
    int studentnumber{};
public:
    ergasia(){};
    ergasia(string t, double g, int n) : title(t), grade(g), studentnumber(n) {};
    void set_title(string t) { title = t; };
    string get_title() { return title; };
    void set_grade(double g) { grade = g; };
    double get_grade() { return grade; };
    void set_sn(double n) { studentnumber = n; };
    double get_sn() { return studentnumber; };
    void set_names(string nm) {
        if (studentnumber < 5) {
            names[studentnumber] = nm;
            studentnumber++;
            cout << "Name is set! there are still " << 5 - studentnumber << "vacanies" << endl;
        cout << "Name isnt't set" << endl;
        }
    };
    string get_names() {
        return names[studentnumber];
    };
    void show() {
        int i;
        cout << "The title is: " << title << endl;
        cout << "hand over date:" << endl; 
        paradosi.display();
        cout << "Grade is :" << grade << endl;
        cout << "foitites: " << studentnumber << endl;
        for (i = 0; i < studentnumber; i++) {
            cout << names[i];
        }
    };
    date paradosi;
};


int main()
{
    ergasia e1;
    e1.set_title("Nanofluids");
    e1.set_grade(10);
    e1.set_sn(5);
    for (int i = 0; i < 5; i++) {
        string name;
        cout << "dwse onoma " << endl;
        cin >> name;
        e1.set_names(name);
    }
    e1.paradosi.set_date(22, 9, 2020);
    e1.show();

    return 0;
}
Id assume you are creating a 5 element name array 0-4 and then attempting to access name[5] which makes it exit the loop b4 it enters the loop in show or even sets the name array.
Hello geovoulg,

I would really like to put your code through a debugger and see what happens, but with out the "include" files you used I can only guess.

A note:
1
2
3
4
5
6
7
class date {
private:  // Not needed as the class is private by default until changed. OK if you leave it.
    double imera{};
    double minas{};
    double etos{};
public:
    date(){};


On line 59 is that a lower case "L" or the number (1)? It is best to avoid using the lower case "L" unless it is part of a larger word.

At the moment I am think that the problem may start in the for loop in line 63 or just the class function.

Andy
Hello geovoulg,

The first thing I did was this:
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
#include <iostream>
#include <string>

class date
{
    private:
    double imera{};
    double minas{};
    double etos{};

    public:
    date() {}
    date(double i, double m, double e) : imera(i), minas(m), etos(e) {}

    void set_date(double i, double m, double e) { imera = i; minas = m; etos = e; }
    double get_date() { return imera; return minas; return etos; }

    void display()
    {
        std::cout << imera << '/' << minas << '/' << etos << '\n';
    }
};

class ergasia
{
    private:
    std::string title{};
    double grade{};
    std::string names[5];
    int studentnumber{};

    public:
    ergasia() {};
    ergasia(std::string t, double g, int n) : title(t), grade(g), studentnumber(n) {};

    void set_title(std::string t) { title = t; };
    std::string get_title() { return title; };

    void set_grade(double g) { grade = g; }
    double get_grade() { return grade; }

    void set_sn(double n) { studentnumber = n; }  // <--- If "studentnumber" is an "int" why is the function trying to set an "int" with a "double"?
    double get_sn() { return studentnumber; }

    void set_names(std::string nm)
    {
        if (studentnumber < 5)
        {
            names[studentnumber] = nm;
            studentnumber++;
            std::cout << "Name is set! there are still " << 5 - studentnumber << " vacanies" << '\n';
            //std::cout << "Name isnt't set" << '\n';
        }

        return; // <--- Used as a break point for testing. Comment or remove when finished.
    }

    std::string get_names()
    {
        return names[studentnumber];
    }

    void show()
    {
        int i;

        std::cout << "\n\nThe title is: " << title << '\n';
        std::cout << "hand over date: ";
        
        paradosi.display();

        std::cout << "Grade is : " << grade << '\n';
        std::cout << "foitites: " << studentnumber << '\n';

        for (i = 0; i < studentnumber; i++)
        {
            std::cout << names[i] << ' ';
        }
    }

    date paradosi;  // <--- This seems to work, but the placement look wrong. A place that seems better would be after the ctors. Or at least before the "show " function.
};


int main()
{
    ergasia e1;

    e1.set_title("Nanofluids");
    e1.set_grade(10);
    //e1.set_sn(5);

    for (int i = 0; i < 5; i++)
    {
        std::string name;

        //std::cout << "dwse onoma " << '\n';
        std::cout << "\nGive a name: ";
        std::cin >> name;

        e1.set_names(name);
    }

    e1.paradosi.set_date(22, 9, 2020);

    e1.show();

    return 0;
}

After the first run line 90 stuck out. This sets "studentnumber" before you even get to the function "set_names" where the if statement fails because "studentnumber" is 5 and 5 is not less than 5.

When I put the comment on line 90 the first output was:

give a name
asdf
Name is set! there are still 4vacanies
Name isnt't set
give a name
qwer
Name is set! there are still 3vacanies
Name isnt't set
give a name
zxcv
Name is set! there are still 2vacanies
Name isnt't set
give a name
yuio
Name is set! there are still 1vacanies
Name isnt't set
give a name
jkl;
Name is set! there are still 0vacanies
Name isnt't set
The title is: Nanofluids
hand over date:
22/9/2020
Grade is :10
foitites: 5
asdfqwerzxcvyuiojkl;



With the adjustments I made it now looks like this:

Give a name: asdf
Name is set! there are still 4 vacanies

Give a name: ghjk
Name is set! there are still 3 vacanies

Give a name: jkl;
Name is set! there are still 2 vacanies

Give a name: qwer
Name is set! there are still 1 vacanies

Give a name: zxcv
Name is set! there are still 0 vacanies


The title is: Nanofluids
hand over date: 22/9/2020
Grade is : 10
foitites: 5
asdf ghjk jkl; qwer zxcv



Not sure what you had in mind for line 52. It gives me the impression that it would be part of an if/else.

Andy
@markyrocks: Thank you markyrocks. The thing is that it normally accepts the five names and no more names, without any prompt or error because it does not give me an cin to enter a 6th name (which is the name[5] element). I didn't quite get what you mean?

@Andy: Andy thanks a lot. Yes I omitted the headers and I apologize. I am giving you the headers in the following lines. No on line 59 it is a (1) not a lowercase L. I am suspecting two code sections: The first is the for loop in line 63 in which I didn't manage to integrate the i variable in the set_names , or, second the set_names fucntion section (lines 31 - 37). For some reason though I can't find the problem.

1
2
3
4
5
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <cstdio> 

 
double get_date() { return imera; return minas; return etos; };


This only returns imera - nor the other values

Also you don't need to terminate a function definition with a ;

1
2
3
4
td::string get_names()
    {
        return names[studentnumber];
    }


This will only return 1 name - not all of them. Also studentnumber is one more than the number entered, so is accessing array out of bounds.

 
e1.set_sn(5);


This sets the entered student numbers to 5 - so no more can be entered!

Consider:

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
#include <string>
#include <iostream>
#include <tuple>
using namespace std;

class date {
	double imera {};
	double minas {};
	double etos {};

public:
	date() {}
	date(double i, double m, double e) : imera(i), minas(m), etos(e) {}
	void set_date(double i, double m, double e) { imera = i; minas = m; etos = e; }
	auto get_date() const { return tuple(imera, minas, etos); }
	void display() const { cout << imera << '/' << minas << '/' << etos << '\n'; }
};

class ergasia {
	string title;
	double grade {};
	string names[5];
	int studentnumber {};

public:
	ergasia() {}
	ergasia(const string& t, double g, int n) : title(t), grade(g), studentnumber(n) {}
	void set_title(const string& t) { title = t; }
	string get_title() const { return title; }
	void set_grade(double g) { grade = g; }
	double get_grade() const { return grade; }
	void set_sn(double n) { studentnumber = n; }
	double get_sn() const { return studentnumber; }

	void set_names(const string& nm) {
		if (studentnumber < 5) {
			names[studentnumber++] = nm;
			cout << "Name is set! there are still " << 5 - studentnumber << " vacanies\n";
		}  else
			cout << "Name isn't set\n";
	}

	const string* get_names() const {
		return names;
	}

	void show() {
		cout << "The title is: " << title << '\n';
		cout << "hand over date:";
		paradosi.display();
		cout << "\nGrade is :" << grade << '\n';
		cout << "foitites: " << studentnumber << '\n';

		for (int i = 0; i < 5 && !names[i].empty(); ++i)
			cout << names[i] << '\n';
	}

	date paradosi;
};

int main()
{
	ergasia e1;

	e1.set_title("Nanofluids");
	e1.set_grade(10);
	//e1.set_sn(5);

	for (int i = 0; i < 5; ++i) {
		string name;

		cout << "dwse onoma: ";
		cin >> name;
		e1.set_names(name);
	}

	e1.paradosi.set_date(22, 9, 2020);
	e1.show();
}




Hello geovoulg,

In regards to what markyrocks said. The array std::string names[5] creates an array of 5 elements. The elements are numbered 0 - 4 because C++ is a zero based language. So using names[5], other than defining the variable, means that you are trying to access the array past the end of the array. This is known as undefined behavior because you have no idea what bit of memory you are trying to access. It is even worse if you write to this memory.

For your header files:
Lines 1 and 2 are fine.

There is nothing from the "cmath" used in the program that I noticed. Have a look at http://www.cplusplus.com/reference/cmath/ to see what is in this header file.

Line 4 I did not include in what I posted, so again it is not needed.

Line 5. Anything that you might use from this header file should be covered under the "iostream" header file.

There is no point in including what you do not need unless you have yet to code something that might need 1 of these header files.


The first is the for loop in line 63 in which I didn't manage to integrate the i variable in the set_names , or, second the set_names function section (lines 31 - 37).


I understand you idea, but if you set "studentnumber" to zero when the object is created it is not a problem. You already did this in your original code line 21.

Since the function "set_names" increment "studentnumber" this is not a problem.

Andy
Ok guys, to begin with, thank you all for your help. Now, I forgot to enter the "else" condition, which I already corrected. Then I looked back to the post to see the replies and I noticed most of you spotted the "e1.set_sn(5);" I used. I corrected this and the code runs fine. However, I have a question regarding this correction.

My goal was to start with setting a class member string names [5] which created an array of 5 strings. I went on by writing the set function for accessing my private name[5] member and I wanted to set the condition that if number of students is going to be less than 5 then the name I will try to set will be set, else it won't! Finally, I used the e1.set_sn(5); so I can set five names (from 0 to 4).

Therefore, my question is, since the string array has 5 elements (0-4) why did the compiler considered "e1.set_sn(5)" as out of bounds?


George
Hello geovoulg,


Therefore, my question is, since the string array has 5 elements (0-4) why did the compiler considered "e1.set_sn(5)" as out of bounds?


Actually the compiler did not consider this to be out of bounds. The function call and function did exactly what it is supposed to do.

The problem is with the if statement in the function "set_names". You wrote: if (studentnumber < 5). To look at it differently: if (5 < 5). This would return false.

By setting the value of "studentnumber" in main before you call "set_names" you are defeating the purpose of the function.

When the program starts the variable "studentnumber" has to have a value of (0) zero for "set_names" to work properly.

Learning how to use the debugger is a great help to see what values variables contain as the program runs.

Or try this:
1
2
3
4
5
void set_names(std::string nm)
{
    std::cout << "\n The student number is: " <<  studentnumber << '\n';  // <--- Used for testing. Comment or remove when finished.

    if (studentnumber < 5)

The poor mans debugger.

Andy
Thanks a lot for explaining Andy. :)
Hello geovoulg,

You are welcome. Any time.

Andy
Topic archived. No new replies allowed.