Sorting Objects

Hey everyone, this is my first post on this site. I have been playing around with C++ a little and I require a bit of help.

I have made this simple program that creates a Student class and asks the user to input a Student I.D, Last Name and First Name. You can store multiple students and the file is output as a .txt file.

The question I have is this...I wish to make it so that the students are stored in order in relation to their I.D number (smallest to largest),

For example,

ID: 011111
Last name: Holland
First Name: Tom

ID: 022222
Last Name: Abode
First Name: Andrew

I have tried using vectors, but it just turned out to be a mess. Any help would be greatly appreciated.

Here is my program...

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
112
113
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;

class Student
{
	private:
		string id;
		string fName;
		string lName;
	public:
		Student();
		~Student();
		void makeFile();
		string getId();
		string getFirstName();
		string getLastName();
};

Student::Student()
{
	id = "N/A";
	fName = "N/A";
	lName = "N/A";
}

Student::~Student()
{
	
}

void makeFile()
{
	fstream newFile("The Program File.txt");
}

string Student::getId()
{
	cout << "Enter the Student ID of the student: ";
	cin >> id;
	return id;
}

string Student::getFirstName()
{
	cout << "Enter the Students first name: ";
	cin >> fName;
	return fName;
}

string Student::getLastName()
{
	cout << "Enter the students last name: ";
	cin >> lName;
	return lName;
}

void setFile(Student student)
{
	ofstream file;
	file.open("The Program File.txt",ios::app);
	if(!file)
	{
		cout << "File couldn't be created :(";
		exit(1);
	}
	else
	{
		file << "I.D Number: " << student.getId() << "\n";
		file << "Last Name: " << student.getLastName() << "\n";
		file << "First Name: " << student.getFirstName() << "\n\n";
		file.close();
	}
}

char next()
{
		char c;
		cout << endl << "Do you wish to input another Student? y/n: ";
		cin>>c;
		cout << endl;
		if (c=='y' || c=='Y' || c=='n' || c=='N')
		{
			return c;
		}
		else
		{
			cout << "You did not enter a valid option!";
			next();
		}
}

void runProg()
{
	char y;
	do
	{
	Student T;
	setFile(T);
	y = next();
	}
	while(y =='y' || y == 'Y');
	cout << endl << "Thank you, have a good day.";
	exit(1);
}

int main()
{
	makeFile();
	runProg();
	return 0;
}




makeFile() is a member of your class.
Yeah woops, shouldn't be there, it didn't affect anything though.
There are two ways to do this in my opinion. One is manipulating the data in ram and then storing it. The other would be storing it then rearranging it. I would prefer the first one. So instead of directly writing to the file you could save your key : in this case ID in an array. Since it is a number you could use the standard qsort algorithm. If you need something more advanced you could use the STL set container and overload the < operator for your student class. Then inserting elements to the Set will mean that those elements are sorted automatically and also printing out to a file is a game :)

Hope that helped :)
Last edited on
Thanks Silvermaul. Yeah so I get it to store the I.D numbers in an array, from there I can sort them numerically however once this is done I have no idea how to assign them back with their original first and last names?
Don't store the I.D's in the arrays. Store the objects themselves or pointers of the objects and sort them by using the I.D as comparison. This way your objects as a whole will be sorted :)
Oh yup, thats what I originally thought of doing before I came onto the forum. I just didn't know how to do it! I will give it another try though, It sounds straight forward!
Thanks man.
Create an operator<() for Student that just returns the comparison for student::id, then store them in a std::set(). They will be in sorted order.
Hi Tomau, I was wondering if you figured out how to do the sorting, because I was facing a similar problem. I had set up a multidimensional array, instead of a class, to store names and numbers in different columns, and wanted to sort the rows of names based on the numbers, highest to lowest. I made my own topic, and someone suggested using classes instead, so I just wanted to know if you were able to figure out the sorting with the classes before I went to rewrite my own code. If possible, can you tell me what sorting code or algorithm you used?
Likely he did as the previous posters suggested; overloading the < operator and inserting into an std::set.
@Kingkurt, Ill let you know if I manage.

@PanGalactic, I am not very familiar with operator overloading and have just been googling but still can't get it to work??
Think of the operator as a plain function :

1
2
3
4
5
6
7
8
9
10
11
12
13
14

class CMyClass
{
public : 
   bool operator < (const CMyClass&arg)
   {
      return this.int32MyValue<arg.int32MyValue;
   }

private : 
   int int32MyValue;

};
In your case, it would look something like this:

1
2
3
4
bool Student::operator<(const Student& other) const
{
    return (id < other.id);
}


Then you would create:

typedef std::set<Student> Students;

However, there are some real problems with your class. You have no way to access the elements without also setting them.

The user I/O should not occur in your getters. The user I/O should be done in a free function or separate class, as should the file I/O.
Last edited on
Hey thanks for the reply's guys! I still couldn't get it to work though, so I think I'll ask a professor once I get back to university in a couple of weeks.
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
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
using namespace std;


struct studentStruct { 
        int scores[5];
        string studName[5];
} studInfo; 

int main(){

	int i,y,t;
        cout << "Please enter the last name of the student and the score of the student, separated by a space" << endl;
        cout << " For example: Doe 88" << endl; 
        vector<studentStruct*> vec; 
        studentStruct * studInfo = new studentStruct; 
        
		for(i=0;i<5;i++)
        cin >> studInfo->studName[i] >> studInfo->scores[i]; 
        vec.push_back(studInfo);


		
		for (i=0;i<5;i++)
	{
		for(int y=0;y<4;y++)
		{
			if(studInfo->scores[y]<studInfo->scores[y+1])
			{
				t=studInfo->scores[y];
				studInfo->scores[y]=studInfo->scores[y+1];
				studInfo->scores[y+1]=t;
			}
		}
	}

for(i=0;i<5;i++)
        cout << vec.at(0)->scores[i] << " " << vec.at(0)->studName[i] << endl; 


        delete studInfo;

	 

system("pause");
	return 0;
}



i have a problem ...a cant sort the names by their scores..
the scores are descending but the names are not..
Topic archived. No new replies allowed.