File sort and linked list

I am having trouble understanding how to create a code where it takes in two files and uses the info from the two files to generate a new file. The first of the two files will contain an ID number, hourly pay and persons name. The second file will contain the ID number and amount of hours they have worked. The file generated is the calculated paycheck they will receive. I am having trouble understanding linked list. I currently store them in a vector but I think it seems redundant to store in a vector and then use a linked list.

When reading in data from a file, is it possible to store it in a linked list?
Is it possible to have the linked list generate new nodes/pointers by itself?
Can linked list be connected to other linked list?
Apologies in advance for the stupid questions.
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
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

void openInputFile(ifstream&inFile);



int main()
{
	int id, hours;
	double wage;
	string name;
	vector<int> IDL;
	vector<double> wageL;
	vector<string> EmployeeL;
	vector<int> hoursWorked;
	ifstream Employee1;
	openInputFile(Employee1);
	while (Employee1 >> id >>wage>>name)
	{
		IDL.push_back(id);
		wageL.push_back(wage);
		EmployeeL.push_back(name);
	}
	
	ifstream HoursWork;
	openInputFile(HoursWork);
	while (HoursWork >> id >> hours)
	{
		hoursWorked.push_back(hours);
	}
	//ofstream Payroll;
	//Payroll.open("Payroll.txt")


	return 0;
}

void openInputFile(ifstream&inFile)
{
	string fileName;
	cout << "Please enter in file name" << endl;
	cin >> fileName;
	inFile.open(fileName);
	while (!inFile) {
		cout << "File not found. Please try again" << endl;
		cout << "Please enter file name" << endl;
		cin >> fileName;
		inFile.clear();
		inFile.open(fileName);
	}

}
class EmployeeList {
	int id;
	double wage;
	string name;
	EmployeeList *next;
public:
	void setID(int ID) { id = ID; }
	void setWage(double Wage) { wage = Wage; }
	void setname(string Name) { name = Name; }

};
Hello angchan,

Looking at your code I would create a vector of type "EmployeeList" where each element of the vector is a complete class with different information. So unless you are required to use a linked list the vector is the best way to go.

For the class either put it in a separate header file or at the beginning of the file before main after the using namespace std; that is best not to use. I would also put the functions of the class in a separate ".cpp" file and bring them all together at compile time. If you are not use to using separate files it is best to put everything above main or if you have a prototype for everything you can put the functions after main.

In the "openInputFile" function the while loop is nice, but what you shoule be doing is an if statement, error message, pause and exit the program because if the file name is wrong there is no reason to continue. If you do not provide the file names that are available then the user will have to leave the program to check the file name. Then again the while loop might work. This is the first time I have seen this approach and will have to test it.

It would also help to have the input file you are using or at least a good sample of the file. Knowing what the file looks lime will help to check how the file is read and how you using the information.

In main when you open the input file you need to check if it is open before you continue otherwise you could end up with nothing. Also your use off the open is incorrect. Something like:
1
2
3
4
5
6
7
8
Employee1.open("File Name");  // <--- or you can use a std::string variable.

if (!Employee1)
{
	std::cout << "\n File " << "File Name" << " did not open" << std::endl;  // <--- "File Name" was a variable.
	std::this_thread::sleep_for(std::chrono::seconds(5));  // <--- Needs header files chrono" and "thread".
	exit(1);  // <--- No point to continue.
}


For the first while loop in main. A good idea, but could be a big problem. In the while condition you are reading the name, but in this way if the name has to parts separated by a space you will only get the first name leaving the last name in the input buffer to be read on the next pass of the loop. With information in the input buffer the next will start with the input buffer and try to put the last name into a numeric variable which will cause the stream to fail, the while loop to end and leave you with a mess and an unfinished read. Not seeing the input file I would more likely read the "id" in the while condition and maybe the wage, but I would put the name inside the loop and use "std::getline(Employee1, name);" to get the whole name I would also precede the getline with:
Employee1.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // <--- Requires header file <limits>. to clear the input buffer.

One thing you have missed is to close your input streams when you are finished with them or at least just before 'return".

I will have to load this up and see if there is anything I have missed.

Hope that helps,

Andy
Hello angchan,

Disregard what I said about opening the file in main. When I separated the lines of code I realized it was a function call. With all the lines running together I missed it.

I created a temporary class in main and used the set functions to load the class and then added the temp class to a vector. At least with what I had to work with it worked and reduced everything to one vector.

I changed the class around a bit:
1
2
3
4
5
6
7
8
9
10
11
12
13
class EmployeeList
{
	private:
		int id;
		double wage;
		std::string name;
	public:
		EmployeeList() { id = 0; wage = 0.0; }  // <--- Added.
		~EmployeeList() {}  // <--- Added.
		void setID(int ID) { id = ID; }
		void setWage(double Wage) { wage = Wage; }
		void setname(std::string Name) { name = Name; }
};

and the while loop in main:
1
2
3
4
5
6
7
8
9
10
while (Employee1 >> id >> wage)
{
	std::getline(Employee1, name);

	temp.setID(id);
	temp.setWage(wage);
	temp.setname(name);

	employee.emplace_back(temp);
}


I did not get as far as the second file yet.

Hope that helps,

Andy
Hi Handy Andy,

I am required to use a linked list.

The files would look like this
File #1
ID ,hourly wage, name
20 5.00 Laura Bell
21 8.25 Jack M. Smith

(there are spaces in between)
File #2
ID hours worked
20 15
21 10

which will generate a file:
Jack M. Smith $82.50
Laura Bell $75



Not sure if the information should be separated
ie

template <class type>
class IDList {
type id;
IDList *next;

public:
IDList() { type newint =type() ; IDList*newnext = nullptr; id = new id; next = new next;}
~IDList(){}
void setID(type ID) { id = ID; }
//generate new data, points to new data, move tail to new data
// { head = id; next = new id; temp = next; tail = next }
};
IDList<int> *head;
IDList<int> *tail;
IDList<int> *temp;



closed account (E0p9LyTq)
I am required to use a linked list.

Instead of using std::vector you can use std::list (double-linked) or C++11's std::forward_list (singly linked).
http://www.cplusplus.com/reference/list/list/
http://www.cplusplus.com/reference/forward_list/forward_list/

Both sequence containers have a sort operation as part of the class template.

Maybe look into std::map or std::multimap instead.
http://www.cplusplus.com/reference/map/map/
http://www.cplusplus.com/reference/map/multimap/

using the ID as the key value for both files. The mapped values could be a std::pair<double, std::string> for the first file and int for the second file.
http://www.cplusplus.com/reference/utility/pair/
FurryGuy-Hi, I would like to use the std::list but my assignment requires me to not use it and create a doubly linked list on my own.
Topic archived. No new replies allowed.