Hello all,

So I am having trouble figuring out a runtime error I am getting in my code. Essentially I read in data and push it into two lists (using the STL list). Then I use the .sort() function to sort the data by average. However I am having a problem. When the list is printed in UNSORTED order, I get an exact copy of my data (a good thing). When I sort the list, one data element is left out and another is replicated ( not good)

Below I have the .dats (both input and output) along with the code to explain the error.

ANY HELP WOULD BE AMAZING the STL is kicking my butt.

Master.dat

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

sorted .dat with error

alexis 8
matthew 10
ethan 23
jacob 28
joyce 33
jones 44
madison 45
ralph 56
pete 56
joseph 56
emma 65
jane 73
smith 74
mavis 77
ashley 83 <--- ashley is put in properly
ashley 83 <--- ashley is reinserted, not correct
joshua 85
thomas 88
michael 89
sue 90
hannah 92 <--- the last ele should be emily 99, however the extra ashley took it out

the source 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;									// |
//-----------------------------------------------------------------------------------------|
struct cProg3										// |
{											// |
	char lname[21];									// |
	float avg;									// |
	int gSize;									// |
	cProg3();									// |
	void Read_m(fstream &Infile);							// |
	void Read_g(fstream &Infile);	
	bool operator < (const cProg3& other) const 					// |
	{										// |
		return (avg < other.avg); //compare by average.				// |
  	};						// |	
											// |
											// |
};											// |
					/***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***/
	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										// |
/******************************************************************************************/

I compiled your code and the only thing I had to change was to delete line 132. When working with iterators like you are you don't need to step one back from the the end. I could not get a duplicate of the data in the output though so I'm not sure why you are

Edited 5 Years Ago by NathanOliver: n/a

I tend to think it would be a problem with reading the file.

This will cause problems:

while(!Infile.eof())

Try instead:

std::string name;
unsigned long age;
while( inFile >> name >> age )
{
//.. use it.
}

Otherwise consult some file IO reference material.

@nathanOliver, removing 132 got emily 99 to come back, any idea why ashley 83 is still being printed twice? She should only be printed once.

@nathanOliver, removing 132 got emily 99 to come back, any idea why ashley 83 is still being printed twice? She should only be printed once.

Yes it's an end-of-file bug because of the way you are reading from the file.

I would bet money on it.

Edited 5 Years Ago by pseudorandom21: n/a

@pseudorandom21, when i try your suggestion, the file does not read in properly...

I cant say what is going on. I would suggest you follow pseudorandom21 advice and change how you read the file in. With that said I did an exact copy and paste of you data file you provided and the code you provided. The only things I changed in your code was to delete line 132 and I commented out lines 94-120 and lines 144-160.

this is the data i used for master.dat

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

and this is what i got in output.dat

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

Make sure you don't have an extra empty line at the end of your input file. I'm pretty sure that is the problem. And your original loop for file-reading is correct.

I dont think its a file read issue purely because if i do not implement the sort, all the data is pushed into the list and printed out just fine.

i think the sort function is doing something crazy. all the data is there.

can you attach you master.dat to the forum so when can have the actual file? You might have to rename it to a .txt file to attach it.

Edited 5 Years Ago by NathanOliver: n/a

Ok, its the file reading that is wrong, I got the same duplicate of ashley by running your code. This should be the file-reading loop:

Prog3.Read_m(Infile);
/***Load Data into List***/
while(!Infile.eof())
{	
  theList.push_back(Prog3);
  Prog3.Read_m(Infile);
};//while

It is due to the fact that some IO stream implementation won't hit end-of-file until a read operation failed.

this is so weird, i just compiled it on my local box, and our schools network share and i get the same error!

haha this is just a wow

Does this work properly given the master.dat input file?

#include <iostream>
#include <fstream>
#include <string>
#include <list>

typedef unsigned int age_type;
//Record type
struct Record{
	std::string name;
	age_type age;
	Record(std::string fname, age_type howOld) : name(fname), age(howOld) {}
	bool operator<(const Record &rhs){
		return this->age < rhs.age;
	}
	std::istream& ReadLine(std::istream &inFile){
		return inFile >> this->name >> this->age;
	}
};

//Convenience function.
std::istream& ReadLine(std::istream &inFile, std::string &word, age_type &age){
	return inFile >> word >> age;
}

//Entry-point
int main()
{
	using namespace std;
	const char *fileName = "master.dat";

	list<Record> inputList;
	fstream inFile(fileName,ios::in);
	if(!inFile.is_open()){
		cerr << "File didn't open.\n";
		return 1;
	}
	string word;
	age_type age = 0;

	while(ReadLine(inFile,word, age)){//<-- using convenience function.
		cout << word << ' ' << age<< endl;
		inputList.push_back( Record(word,age) );
	}
	inFile.close();
	inputList.sort();

	cin.get();
}

I see that the thread kept up last night, but as mike_2000_17 pointed out, it was because I did not "prime" my while loop during the read. That was what fixed my problem and I also has a "duh" moment when I looked back at notes from the past.

So PRIME THE WHILE lol.

I am going to close the thread, however any insights as to why the code will produce strange answers if the loops is not "primed"?

Thanks for all the help guys,

AtticusR5

This question has already been answered. Start a new discussion instead.