Hello all,

I know there is a "sort" method in the STL for list. However I am not sure how to use it, and my research was unable to help me out. What I am trying to do is sort my master list by the averages, lowest to highest.

Can anyone give me clues as how to use the STL sort to do this?

Thanks

/*******************************************************************************************
Devang N. Joshi										   *
CSCI 271 										   *
Assignment Three									   *
February 19th, 2011									   *
STL Double Linked List									   *
											   *
The purpose of this assignment is to gain experiance using C++ built in List STL	   *
/******************************************************************************************/
#include <iostream>									// |
#include <iomanip>									// |
#include <fstream>									// |
#include <cstdlib>									// |
#include <cstring>									// |
#include <cmath>									// |
#include <list>										// |
using namespace std;									// |
//-----------------------------------------------------------------------------------------|
struct cProg3										// |
{											// |
	char lname[21];									// |
	float avg;									// |
	int gSize;									// |
	cProg3();									// |
	void Read_m(fstream &Infile);							// |
	void Read_g(fstream &Infile);							// |	
											// |
											// |
};											// |
					/***Functions**/				// |
//-----------------------------------------------------------------------------------------|
cProg3::cProg3()									// |
{											// |
	strcpy(lname,"");								// |
	avg = 0;									// |
	gSize = 0;									// |
}											// |
//-----------------------------------------------------------------------------------------|
void cProg3::Read_m(fstream &Infile)							// |
{ Infile>>lname>>avg; }									// |
//-----------------------------------------------------------------------------------------|
void cProg3::Read_g(fstream &Infile)							// |
{ Infile>>lname>>gSize; }								// |
//-----------------------------------------------------------------------------------------|					
					/***MAIN***/					// |
//-----------------------------------------------------------------------------------------|
int main()										// |
{											// |
//-----------------------------------------------------------------------------------------|
	/***File Handlers***/								// |
	fstream Infile;									// |	
	fstream Outfile;								// |
											// |
	/***Class Decleration***/							// |
	cProg3 Prog3;									// |
											// |
	/***List Decleration***/							// |
	list<cProg3>theList;		     //the list for master.dat			// |
	list<cProg3>groupList;		     //the list for groups.dat			// |
	list<cProg3>::iterator it_m;	     //master list iterator			// |
	list<cProg3>::iterator it_g;         //groups list iterator			// |
	list<cProg3>::iterator loopCount_m;  //for read & write loops in master list	// |
	list<cProg3>::iterator loopCount_g;  //for read & write loops in groups list    // |
//-----------------------------------------------------------------------------------------|
	/***Open Master Data and error check***/					// |				
	Infile.open("master.dat",ios::in);						// |
	if(!Infile)									// |
	{										// |
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;				// |
		exit(1);								// |
											// |
	}										// |
	else										// |
	{										// |
											// |
		cout<<"Master Data File Found & Opened"<<endl;				// |
											// |
		/***Load Data into List***/						// |
		while(!Infile.eof())							// |
		{									// |	
			Prog3.Read_m(Infile);						// |
			theList.push_back(Prog3);					// |
											// |
		};//while								// |
											// |
		cout<<"Master Data File Loaded into List"<<endl<<endl;			// |
		Infile.close();								// |
											// |
	}										// |
//-----------------------------------------------------------------------------------------|
	/***Open Groups Data and error check***/					// |					
	Infile.open("groups.dat",ios::in);						// |
	if(!Infile)									// |
	{										// |
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;				// |
		exit(1);								// |
											// |
	}										// |
	else										// |
	{										// |
											// |
		cout<<"Groups Data File Found & Opened"<<endl;				// |
											// |
		/***Load Data into Array***/						// |
		while(!Infile.eof())							// |
		{									// |
			Prog3.Read_g(Infile);						// |
			groupList.push_back(Prog3);					// |
											// |
		};//while								// |
											// |
		cout<<"Groups Data File Loaded into List"<<endl<<endl;			// |
		Infile.close();								// |
											// |
	}										// |
//-----------------------------------------------------------------------------------------|
	/***Sort List***/
	it_m = theList.begin();
	loopCount_m = theList.end();
	theList.sort();
		
											// |
//-----------------------------------------------------------------------------------------|
	/***Print Lists Back Out**/							// |
	Outfile.open("output.dat",ios::out);						// |
//-----------------------------------------------------------------------------------------|
	/***Print Master List***/							// |
											// |
	loopCount_m = theList.end();         //sent loop counter to end of list		// |
	loopCount_m--;		             //move one position back for proper output	// |
	it_m = theList.begin();	             //set iterator to begining of list		// |
											// |
	while(it_m != loopCount_m)							// |
	{										// |
		cout<<it_m->lname<<" "<<it_m->avg<<endl;				// |
		Outfile<<it_m->lname<<" "<<it_m->avg<<endl;				// |
		it_m++;									// |
											// |
	};//end loop									// |
	cout<<endl<<endl;								// |
	Outfile<<endl<<endl;								// |
//-----------------------------------------------------------------------------------------|
	/***Print Group List***/							// |					
											// |
	loopCount_g = groupList.end();       //sent loop counter to end of list		// |
	loopCount_g--;		             //move one position back for proper output // |
	it_g = groupList.begin();	     //set iterator to begining of list		// |
											// |
	while(it_g != loopCount_g)							// |
	{										// |
		cout<<it_g->lname<<" "<<it_g->gSize<<endl;				// |
		Outfile<<it_g->lname<<" "<<it_g->gSize<<endl;				// |
		it_g++;									// |
											// |
	};//end loop									// |
	cout<<endl<<endl;								// |
	Outfile<<endl<<endl;								// |
//-----------------------------------------------------------------------------------------|
	Outfile.close();								// |
											// |
	return 0;									// |
											// |
}//end main										// |
/******************************************************************************************/

to sort the list using sort you would have to do

sort(theList.first(), theList.end(), compareFunction);

the compareFunction is one that you would have to write to compare the avg of one object to the avg of another object. this should help you out.

@NathanOliver: The <algorithm> version of sort cannot be used for the list container because it requires a random-access iterator (and list is a linked-list so it only provides a Forward and Backward Iterator concept). The way the OP did is correct.

@atticusr:
The sorting algorithm relies on the comparison (by default) of two elements using the < (less-than) comparison. So, the underlying type has to have that operator defined. In other words, if you have "list<MyType> l; MyType a, b;", you have to be able to write "a < b". To be able to do that for a custom type, you need to overload the operator <. As so:

struct cProg3
{
  char lname[21];
  float avg;
  int gSize;
  cProg3();
  void Read_m(fstream &Infile);
  void Read_g(fstream &Infile);
  //Overload operator < here:
  bool operator < (const cProg3& other) const {
    return (avg < other.avg); //compare by average.
  };
};

That should work.

commented: thanks for straightening me out with that +2

@mike_2000_17, just to make sure I understand what you did with the overload,

bool operator overload < as a bool variable, that works on the struct cProg3 (and is a const). This will allow it to access the struct member 'avg' and make the comparison and return either a true or false, which the .sort() function can then use?

Does that sound about right? I just want to make sure I have the understanding locked down.

@nathanOliver, thanks to you too for the link and the example!

atticusr5

>>Does that sound about right? I just want to make sure I have the understanding locked down.
It looks like you have the right idea.

If you make an operator function a member of a class/struct (or a friend of the class/struct) it will have access to the data members just like any other member function and the compiler will automatically call it under the correct circumstances.

Great good trick to know. Thanks again everyone!