/**
 * Program Filename: Lab12e1.cpp
 * Authur: ZHU, Xiaoqing
 * Created: 4/11/98
 * Modified:
 * Description:
 * This program creates linked list, it reads data from file and then
 * at the end it deletes list.
 *
 * This program basicly is a review of last lab's content, but we 
 * introduced the idea of dividing a linked list node into two fields,
 * a data field and a next pointer field, to separate the content from
 * the implementation.
 */
#include <iostream.h>
#include <fstream.h>
#include <string.h>
/**
 * the input file
 */
#define INPUT_FILE "a:list.in"
/**
 * constant
 * the maximum length of names
 */
const int MAXNAME = 16;
/**
 * structure People
 * stores information of a person with his/her name, id and age
 */
struct People
{
	char fname[MAXNAME];
	char lname[MAXNAME];
	int  id;
	int  age;
};
/**
 * the linklist node type
 * another structure that has People as its data field and
 * next as its link field
 *
 * using this approach we can change the content of the data field
 * without modifying linklist operation
 */
struct Node
{
	People people;
	Node  *next;
};
/**
 * Function prototypes
 */
Node* readList( Node* ); // read a list from the input file
Node* readNode( ifstream& ); // read a people struct from the input file
Node* addToList( Node*, Node* ); // add a node to the list
Node* deleteList( Node* ); // delete all the nodes in the list
void  printList( Node* ); // print the whole list
void  printPeople( const People& ); // print one people
void  Wait(); // prompt user to press any key to continue...
/**
 * main program begins
 */
int main()
{
	Node *PeopleList = NULL; // public safety issue
lab12-1.gif (1433 bytes)
	// now we read the list from the pre_defined input file
	PeopleList = readList( PeopleList );

// NOW go the function readList


/**
 * Function: readList
 * Description: Reads the data from a file and calls function readPeople
 *     will create list and put those data read from the file in the list
 * Parameters: list - the linked list header pointer
 * Returns: the linked list with data
 */
Node* readList( Node *list )
{
lab12-2.gif (1254 bytes)
	ifstream cinf;
	Node *newNode = NULL;
lab12-3.gif (1374 bytes)
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {

// now go to function readNode
// Lets assume the input file "list.in" contains the following data

 

1234
23
John
Smith
5678
43
Bob
Brown
9012
32
Bill
Johnson

/**
 * Function: readNode
 * Description: This function will read one people's data from
 *     the file, allocate the memory and return the node
 *     Notice the combination use of get and ingore in input
 * Parameters: cinf - the reference to the input file
 * Returns: a pointer to the new node
 */
Node* readNode( ifstream &cinf )
{
	int id;
	Node *newNode;
lab12-4.gif (1339 bytes)
	cinf >> id;
	
	if ( !cinf.eof() ) {
		newNode = new Node;
lab12-5.gif (2763 bytes)		newNode->people.id = id;
		cinf >> newNode->people.age;
		cinf.ignore( 200, '\n' );
		cinf.get( newNode->people.fname, MAXNAME );
		cinf.ignore( 200, '\n' );
		cinf.get( newNode->people.lname, MAXNAME );
		cinf.ignore( 200, '\n' );
		newNode->next = NULL;
lab12-6.gif (3031 bytes)
		return newNode;
	} else {
		return NULL;
	}
}

// NOW return to readList function

 

Node* readList( Node *list )
{
	ifstream cinf;
	Node *newNode = NULL;
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {
//------>> return here
lab12-7.gif (3404 bytes)
		list = addToList( list, newNode );

//NOW call addToList


/**
 * Function: addToList
 * Description: Creates a new node and add it to the head of the linked
 *              list
 * Params: list - the linked list header pointer
 *         newnode - a pointer to the new node
 * Returns: the new header pointer
 */
Node* addToList( Node *list, Node *newnode )
{
	Node *newheader;
	newnode->next = list; // add to the head
	newheader = newnode;
lab12-8.gif (3992 bytes)
	return newheader;
}

// NOW return to readList


 

Node* readList( Node *list )
{
	ifstream cinf;
	Node *newNode = NULL;
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {
		list = addToList( list, newNode );
lab12-9.gif (3597 bytes)
	}

// Now do loop again - call readNode a second time


 

Node* readNode( ifstream &cinf )
{
	int id;
	Node *newNode;
	cinf >> id;
	
	if ( !cinf.eof() ) {
		newNode = new Node;
		newNode->people.id = id;
		cinf >> newNode->people.age;
		cinf.ignore( 200, '\n' );
		cinf.get( newNode->people.fname, MAXNAME );
		cinf.ignore( 200, '\n' );
		cinf.get( newNode->people.lname, MAXNAME );
		cinf.ignore( 200, '\n' );
		newNode->next = NULL;
lab12-10.gif (3010 bytes)
		return newNode;
	} else {
		return NULL;
	}
}

// NOW return to readList


 

Node* readList( Node *list )
{
	ifstream cinf;
	Node *newNode = NULL;
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {
lab12-11.gif (3708 bytes)
		list = addToList( list, newNode );

// Now call addToList a second time


 

Node* addToList( Node *list, Node *newnode )
{
	Node *newheader;
	newnode->next = list; // add to the head
	newheader = newnode;
lab12-12.gif (4533 bytes)
	return newheader;
}

// Now return to readList


 

Node* readList( Node *list )
{
	ifstream cinf;
	Node *newNode = NULL;
	cinf.open( INPUT_FILE );
	// read data now
	while ( (newNode = readNode(cinf)) != NULL ) {
		list = addToList( list, newNode );
lab12-13.gif (4319 bytes)
	}

// Now do loop again can call readNode a third time
// but I won't repeat the code - just show the picture

lab12-14.gif (2505 bytes)

// returning to readList  we have

lab12-15.gif (4813 bytes)

// now call addToList the third time


 

Node* addToList( Node *list, Node *newnode )
{
	Node *newheader;
	newnode->next = list; // add to the head
	newheader = newnode;
lab12-16.gif (5558 bytes)
	return newheader;
}
	cinf.close();
	return list;
}

// Now return to readList again


lab12-17.gif (4983 bytes)


If this was the end of file, the next call to readNode, would detect this after trying to input and it would return NULL

This would cause readList to break out of its loop, close the file and return a pointer to the beginning of the list.

Returning back to the main function

 

int main()
{
	Node *PeopleList = NULL; // public safety issue
	// now we read the list from the pre_defined input file
	PeopleList = readList( PeopleList );
lab12-18.gif (4495 bytes)
	// we print the list to view its data after reading
	printList( PeopleList );
	Wait();
	// now we flush the list
	PeopleList = deleteList( PeopleList );
	// then print the list again
	printList( PeopleList );
	// now delete the whole list
	return 0;
}