Lines 163-167 don't do anything. Did you mean to assign something to those members?
Line 176 causes it to return after inserting the first person.
Lines 184-186: it looks like you're inserting at the end of the list. Was this way you intended? It's much faster to insert at the beginning of a linked list.
Lines 190-194: same problem as lines 163-167.
In addition, insertFromFile returns a string, but you're returning a pointer to struct Personnel.
I think you need to reorganize the code. There should be just one function that inserts into a list. When you want to insert from a file, you read the file, and then call the function to insert into the list. When you want to read from cin, you read the person there and then call the function to insert.
Think of it this way: the purpose of your functions and methods is NOT to "do all the work." Their purpose is to "make doing the work easy." If you approach coding this way you'll create nice reusable code.
For example, take class Personnel. You need to be able to read it from a file, or prompt for the data from the user, and you need to be able to print it out. So create those methods:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
struct Personnel
{
Personnel() : next(NULL) {} // always initialize next to NULL
string firstName;
string lastName;
string jobTitle;
char empStatus;
double wage;
Personnel *next;
bool read(istream &is); // read from an open file, or any stream
void print(ostream &os); // print to open file or any stream
bool fromUser(); // prompt and read from user on cin
};
|
...
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
|
// read from an open file, or any stream
bool Personnel::read(istream &is)
{
is >> firstName >> lastName >> jobTitle >> empStatus >> wage;
return is.good();
}
// print to open file or any stream
void Personnel::print(ostream &os)
{
os << firstName << endl;
os << lastName << endl;
os << jobTitle << endl;
os << empStatus << endl;
os << wage << endl;
}
// prompt and read from user on cin
bool Personnel::fromUser()
{
cout << "Enter person's data:" << endl;
cout << "First Name: ";
cin >> firstName;
cout << "Last Name: ";
cin >> lastName;
cout << "Job Title: ";
cin >> jobTitle;
cout << "Employments Status <F>ull or <P>art time: ";
cin >> empStatus;
cout << "Wage: ";
cin >> wage;
return cin.good();
}
|
Now let's think about the list itself. You can add a node to the list and you can print it out:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
struct List {
List() : root(NULL) {}
// Delete all items in the list
~List();
// Add a node to the front of the list. node MUST be allocated
// via new. The List will be responsible for deleting it.
void add(Personnel *node);
// Print the list to the stream
void print(ostream &os);
private:
Personnel *root; // head of the list
};
|
...
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
|
void
List::print(ostream &os)
//=======================================
// PRINT LIST CONTENTS
//=======================================
{
Personnel *next_ptr;
next_ptr = root;
if (next_ptr == NULL) {
os << "EMPTY LIST: No nodes to print...." << endl;
} //end if
else {
while (next_ptr != NULL) {
next_ptr->print(os); // use the print() method that we defined above
next_ptr = next_ptr->next;
} //end while
} //end else
} //end print_list
//=====================Add node by manual input.
void
List::add(Personnel * node)
//=========================================
// ADD A NEW NODE
//=========================================
{
node->next = root;
root = node;
}; //end Personnel
List::~List()
{
// ADD CODE to delete all items in the list.
}
|
As indicated, you will need to add the code to delete the items from the list when it is destroyed.
Notice how short the add() method has become
. When you add to the front of the list, it's only 2 statements.
Now let's look at inserting from a file. Remember, you want to "make doing the work easy." So let's make this a method of the list. And just like with print, let's pass in the stream:
struct List {
...
void insertFromFile(istream &is);
...
};[/code]
And that code becomes:
1 2 3 4 5 6 7 8 9 10
|
void
List::insertFromFile(istream &is)
{
Personnel *node = new Personnel;
while (node->read(is)) {
add(node);
node = new Personnel;
}
delete node; // You created one but couldn't read it. Delete it now.
} //end insertFromFile
|
Notice how I use the read() method from personnel to read the node from the stream. Note that the read() method returns true or false depending on whether it succesfully read the record, and I'm using that return value in the while() loop. I'm also using the add() method to add the node to the list. The one tricky part here is that when read() finally fails, you have to delete the last node that you created.
But you still need to get the file name and open it. Let's move that to the code inside menu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
void
menu()
{
List list;
...
case '1':
{
string fileName = getFileName();
ifstream file;
file.open(fileName.c_str());
if (!file.is_open()) {
cout << "File did not open." << endl;
exit(EXIT_FAILURE);
} // end if
list.insertFromFile(file);
}
break;
|
Now all you have to do is change the code for add_node(). It just needs to create a new Personnel object, call fromUser() on it to prompt the user and read the data, and then insert it in the list.