Hello all,

So I am new to the whole STL List class, and I am a little confused. In the past I have always had two classes, a data class and a "linked list" class. So now I have a bit of a pickle when I try to make a list of objects using the STL. Essentially I have a class and I want to be able to read in many classes into the list. But I do not understand how to insert an object using the STL implementation. (list.insert() <---what do i put in the () )

I'm a noob to the STL list so its throwing me off!

Thanks in advance

/***************************
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;

class cProg3
{
	private:
		char lname[21];
		float avg;
		int gSize;

	public:
		cProg3();
		void Read_m(fstream &Infile);
		void Read_g(fstream &Infile);
		void Load();

};
/***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; }
//------------------------------

int main()
{
	/***File Handlers***/
	fstream Infile;
	fstream Outfile;

	/***Class Decleration***/
	cProg3 Prog3,temp;

	/***List Decleration***/
	list<cProg3> theList;
	list<cProg3>::iterator it;


	/***Open Master Data and error check***/
	Infile.open("/home/win.thackerw/271/peer/master.dat",ios::in);
	if(!Infile)
	{
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;
		exit(1);
		
	}
	else
	{
		
		cout<<"File Found & Opened"<<endl;

		it = theList.begin();
		it++;				
		while(!Infile.eof())
		{
			Prog3.Read_m(Infile);
			theList.insert(it,temp);
			it++;

		}//while
		
	}
	





	return 0;

}//end main

The insert function is only if you want to insert an element at a particular position in the list. For regular insertions of elements (at the end or at the beginning), you use the functions push_back() or push_front() (for inserting at the end or at the beginning, respectively). Basically, most STL containers use a terminology akin to a queue or a stack ("push" to add, "pop" to remove). The insert and erase functions are for adding and removing an element at a specific position (positions are marked using an "iterator"). So, your file-reading loop should probably look more like this:

while(!Infile.eof())
  {
    Prog3.Read_m(Infile);
    theList.push_back(Prog3);
  }//while

NOTE: You are using a wrong wording in your question. I think you are confusing the concepts of a _class_ and an _object_. A class is the type (like int or double), while the object is the variable. So, in your code, Prog3 and temp3 are objects of the class cProg3. It's an important distinction to make.

I was just about to post an amendment to my question, however I figured out how to add to the list, now just how to print out. I used the .insert method to put everything into a list, and looking back it seems like a "duh" moment. However if i wanted to print the list, how would i do that?

/***************************
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;

class cProg3
{
	private:
		char lname[21];
		float avg;
		int gSize;

	public:
		cProg3();
		void Read_m(fstream &Infile);
		void Read_g(fstream &Infile);
		void Print_s();
		void Print_f(fstream &Outfile);

};
/***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; }
//-----------------------------------
void cProg3::Print_s()
{
	cout<<lname<<" "<<avg<<endl;
}
//-----------------------------------
void cProg3::Print_f(fstream &Outfile)
{
	Outfile<<lname<<" "<<avg<<endl;
}
//-----------------------------------

int main()
{
	int i=0; //loop variable

	/***File Handlers***/
	fstream Infile;
	fstream Outfile;

	/***Class Decleration***/
	cProg3 Prog3;

	/***List Decleration***/
	list<cProg3> theList;
	list<cProg3>::iterator it;


	/***Open Master Data and error check***/
	Infile.open("/home/win.thackerw/271/peer/master.dat",ios::in);
	if(!Infile)
	{
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;
		exit(1);
		
	}
	else
	{
		
		cout<<"File Found & Opened"<<endl;

		it = theList.begin();
		it++;				
		while(!Infile.eof())
		{
			Prog3.Read_m(Infile);
			theList.insert(it,Prog3);
			it++;

		}//while
		cout<<"Data loaded onto array"<<endl<<endl;
		Infile.close();
		
	}
	
	Outfile.open("output.dat",ios::out);

	it = theList.begin();	
	for(it; it != theList.end(); it++) 
	{
		Prog3.Print_s();		//<-----how do you go back down and print out each element??
		Prog3.Print_f(Outfile);
	}
	
	return 0;

}//end main

Consider making your print functions const-correct. void cProg3::Print_s() const etc.

There are many ways to print out the elements in an STL sequence.
You could iterate through the sequence (as you have done). You could use a standard algorithm along with a function object (or a lambda function if you are using a newer compiler eg. Microsoft 2010).

#include <list>
#include <algorithm>
#include <functional>

struct cProg3 { /*...*/ void print_s() const { /*...*/ } /*...*/ } ;

void print_list_one( const std::list<cProg3>& lst )
{
    for( std::list<cProg3>::const_iterator iter = lst.begin() ;
          iter != lst.end() ; ++iter ) iter->print_s() ;
}

void print_list_two( const std::list<cProg3>& lst )
{ std::for_each( lst.begin(), lst.end(), std::mem_fun_ref(&cProg3::print_s) ) ; }


void print_list_three( const std::list<cProg3>& lst )
{ std::for_each( lst.begin(), lst.end(), []( const cProg3& c ) { c.print_s() ; } ) ; }

There is always the ostream methods e.g.

void print_list_four(const std::list<cProg3>& lst)
{
  copy(lst.begin(),lst.end(),std::ostream_iterator<cProg3>(std:cout,""));
}

However, you will want two things, (1) to change your void Print_f(fstream &Outfile); to something slightly more general. void Print_f(std::ostream&) const; and (2) to add this functions

std::ostream&
operator<<(std::ostream& OutStream,const cProg3& A) const
{
   A.Print_f(OutStream);
   return OutStream;
}

Effectively you are giving your class a operator<< and then using with a functional.

However, there are a lot of ways to do this, and the difficulty is choosing the most appropriate.

Ok so before I try the other suggestions, I tried out some new things in my code and I have it "sort of working" Again the idea is to read a data file into a list and then print it out again. However I am unable to do so. Many of the values are correct, but a few are repeated and I do not know why. Below is the code, and the data file I am using to run in Linux

CODE:

/***************************
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;

class cProg3
{
	private:
		

	public:
		char lname[21];
		float avg;
		int gSize;
		cProg3();
		void Read_m(fstream &Infile);
		void Read_g(fstream &Infile);
		void Print_s();
		void Print_f(fstream &Outfile);
		

};
/***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; }
//-----------------------------------
void cProg3::Print_s()
{
	cout<<lname<<" "<<avg<<endl;
}
//-----------------------------------
void cProg3::Print_f(fstream &Outfile)
{
	Outfile<<lname<<" "<<avg<<endl;
}
//-----------------------------------

int main()
{
	int i=0; //loop variable

	/***File Handlers***/
	fstream Infile;
	fstream Outfile;

	/***Class Decleration***/
	cProg3 Prog3;

	/***List Decleration***/
	list<cProg3>theList;
	list<cProg3>::iterator it;


	/***Open Master Data and error check***/
	Infile.open("master.dat",ios::in);
	if(!Infile)
	{
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;
		exit(1);
		
	}
	else
	{
		
		cout<<"File Found & Opened"<<endl;

		it = theList.begin();
		it++;	
		Prog3.Read_m(Infile);
		theList.insert(it,Prog3);			
		while(!Infile.eof())
		{
			it++;			
			Prog3.Read_m(Infile);
			theList.insert(it,Prog3);
			

		}//while*/

		cout<<"Data loaded onto array"<<endl<<endl;
		Infile.close();
		
	}
	
	Outfile.open("output.dat",ios::out);

	it = theList.begin(); 	//set iterator to begining of the list
	it++; 			//agument the list iterator to first element
	cout<<it->lname<<" "<<it->avg<<endl;
	Outfile<<it->lname<<" "<<it->avg<<endl;
	while(it != theList.end()) 
	{
		cout<<it->lname<<" "<<it->avg<<endl;
		Outfile<<it->lname<<" "<<it->avg<<endl;
		it++;
	}
	
	Outfile.close();
	
	return 0;

}//end main

DATA FILE

jones 44
smith 74
thomas 88
ralph 56
sue 90
jane 73
mavis 77
joyce 33
pete 56
jacob 28
emily 99
michael 89
madison 45
joshua 85
hannah 92
matthew 10
emma 65
ethan 23
alexis 8
joseph 56
ashley 83

Line 115 should be moved to in-between line 117 and 118. However, the canonical (or idiomatic) way to do this kind of loop (from line 114 to 123) is:

for(it = theList.begin(); it != theList.end(); ++it) { //for all elements of theList
  cout << it->lname << " " << it->avg << endl;         //output the record to the terminal
  Outfile << it->lname << " " << it->avg << endl;      //save the record to the file
};

Much simpler, isn't it?

The same goes for lines 94 to 105:

while(!Infile.eof()) {       //while there are still elements in the file.
  Prog3.Read_m(Infile);      //read the values;
  theList.push_back(Prog3);  //add the record to the end of the list.
};

As others have suggested, there are more "advanced" ways to do these simple loops (with overloads, functionals, nameless functors, or lambdas), but that's not for you to worry about at this stage.

Edited 5 Years Ago by mike_2000_17: n/a

Thanks for the help everyone, this is what I ended up doing in order to get the list both read in and printed properly:

/***************************
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;

class cProg3
{
	private:
		

	public:
		char lname[21];
		float avg;
		int gSize;
		cProg3();
		void Read_m(fstream &Infile);
		void Read_g(fstream &Infile);
		void Print_s();
		void Print_f(fstream &Outfile);
		

};
/***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; }
//-----------------------------------
void cProg3::Print_s()
{
	cout<<lname<<" "<<avg<<endl;
}
//-----------------------------------
void cProg3::Print_f(fstream &Outfile)
{
	Outfile<<lname<<" "<<avg<<endl;
}
//-----------------------------------

int main()
{
	int i=0; //loop variable

	/***File Handlers***/
	fstream Infile;
	fstream Outfile;

	/***Class Decleration***/
	cProg3 Prog3;

	/***List Decleration***/
	list<cProg3>theList;
	list<cProg3>::iterator it;	  //general iterator
	list<cProg3>::iterator loopCount; //for read & write loops


	/***Open Master Data and error check***/
	Infile.open("master.dat",ios::in);
	if(!Infile)
	{
		cerr<<"FILE NOT FOUND!!!!!!!!!!!!!"<<endl;
		exit(1);
		
	}
	else
	{
		
		cout<<"File Found & Opened"<<endl;

		while(!Infile.eof())
		{
			Prog3.Read_m(Infile);
			theList.push_back(Prog3);

		};//while

		cout<<"Data loaded onto array"<<endl<<endl;
		Infile.close();
		
	}
	
	Outfile.open("output.dat",ios::out);

	loopCount = theList.end();
	loopCount--;
	it = theList.begin();
		
	while(it != loopCount)
	{
		cout<<it->lname<<" "<<it->avg<<endl;
		Outfile<<it->lname<<" "<<it->avg<<endl;
		it++;

	};//end loop
	
	Outfile.close();
	
	return 0;

}//end main
This question has already been answered. Start a new discussion instead.