Warmup C++ Assignment

Assigned on Monday, April 1.
Due on Friday, April 5.


Introduction

The purpose of this assignment is to get you acquainted with some particular aspects of C++ and Unix in order to prepare you for the course project. It will illustrate C-strings, the fstream libraries, and other C++ features. It will also demonstrate the use of Makefiles in the sense that we will be using them in the Minibase project.

Keep in mind that we won't actually be covering C++ content in class. Since you may or may not have seen some of the C++ syntax used in the Minibase assignments, I have included links on the course webpage to references that should be helpful.


Getting Started

Before you start, you need to add the following line to your .cshrc file in your home directory:

setenv MINIBASE_ROOT /usr/local/minibase-2.0

(Important: make sure you hit "Enter" at the end of the above line.)

Close your terminal window, then open up a new one.

Create a new directory called cplspls in which to begin working on your program. This is crucial for minibase assignments: you should work on each project in its own directory. On the department systems, copy the file /usr/local/mini_hwk/assign/cplspls/src/Makefile to your current directory. To obtain the rest of the files that you will need, type make setup .

Now take a look at your directory by issuing an ls .You should have all the files that you need to work on the assignment. If you type make you will notice that there is a missing file called emplist.C. Your job in this assignment is to implement this file. This is how all our project assignments will work: the directory will contain some code related to the assignment, but will be missing some code. You will have to supply the missing code.

Take a look at the file Makefile. You are free to add more C++ files other than the ones already specified in the assignment, but if you do so you will have to add these files to the Makefile.


What You Have to Do

You will have to implement a class that manages a singly linked list of EmployeeNode objects storing information about employees. Each EmployeeNode object stores the name and salary of an employee. The employee name is a null-terminated character string, and the salary is an integer.

One of the main operations that you have to implement for an employee list is reading employee information from a binary file and adding it to the list. The format of this binary file is described below. The employee list is always maintained sorted alphabetically by employee name. The employee records in the files used to populate the list are also sorted alphabetically by employee name. You should be able to read a file containing employee records into an empty list, or into a list that already contains employee nodes. In the latter case, the records read from the file should be merged with the nodes already in the employee list so that the list remains sorted by employee name.

Here are the declarations of the employee list classes. These declarations can be found in emplist.h. You are free to add to these classes any private/protected members that would help you with the implementation.

// A node in the employee list.
class EmployeeNode{
private:
	char *name;
	int salary;
	EmployeeNode *next;  // Pointer to the next node in the list.

public:
	EmployeeNode ();
	~EmployeeNode ();

	// Set and get methods for employee information.
	void setName (const int nameLen, const char* const nameIn);
	void setSalary (const int salaryIn);
	void setNextNode (EmployeeNode* const nextIn);
	char *getName ();
	int getSalary () const;
	EmployeeNode *getNextNode ();

	// Print employee information to standard output (the screen).
	void printEmployee () const;
}; //class EmployeeNode

// The employee list class.
class EmployeeList{
private:
	EmployeeNode *head;  // Pointer to the head of the employee list.

public:
	EmployeeList ();
	~EmployeeList ();

	// Read employee information from a file, or write the entire
	// employee list to a file.
	int readFromFile (const char* const filename);
	int writeToFile (const char* const filename) const;

	// Traverse the list to get the number of employee nodes, or the
	// average salary of all employees.
	int getNumEmployees () const;
	double getAverageSalary () const;

	// Print the employee list to standard output (the screen).
	void print () const;
}; //class EmployeeList

Notes on the Implementation


Format of Employee Files

Each employee file is a binary file that stores a sequence of variable length employee records. Each employee record has two fields: name (variable length) and salary (4 byte integer). The format of an employee record is as follows:
  ------------------------------ ... -----------------------------------------
 |    4 byte integer     |     N character string     |    4 byte integer     |
 | Number of characters  |        Employee name       |    Employee salary    |
 | in employee name (N)  |    (not null-terminated)   |                       |
  ------------------------------ ... -----------------------------------------

To read integers and character strings from a binary file you can use:

	fstream infile(filename,ios::in | ios::binary);
	int nameLen;
	char *name;
	infile.read((char*)&nameLen,sizeof(int));
	... allocate memory for name ...
	infile.read(name,nameLen);
	... add the null character, '\0', to the end of the name ...
Reading nameLen shows an example of type casting in C++.

To write integers and character strings to a binary file you can use:

	fstream outfile(filename,ios::out | ios::binary);
	int nameLen = ...;
	char *name = ...;
	outfile.write((char*)&nameLen,sizeof(int));
	outfile.write(name,nameLen);

When you are done with implementing the employee list classes, you should be able to type make and have your code compile to give an executable called elproc. Run this executable to test your code.


Testing Your Code

The file main.C contains code that tests your employee list class. First, it reads the file inputlist.dat into an employee list, l. Next, it reads a file secondlist.dat into the same employee list, l. After that it prints the employee list, and computes and prints the number of employees and their average salary. It then writes the employee list to the file mergedlist.dat.

inputlist.dat contains the following records:

Name            Salary
----            ------
Brown, Steve    82
Chen, Jessica   75
Engelbart, Mark 30

secondlist.dat contains the following records:

Name            Salary
----            ------
Abel, John      25
Dickson, Eric   65
Fredrik, Cathy  50

The expected mergedlist.dat file is in mergedlist.dat.correct. The screen output of your program should look something like this:

Name            Salary
----            ------
Abel, John      25
Brown, Steve    82
Chen, Jessica   75
Dickson, Eric   65
Engelbart, Mark 30
Fredrik, Cathy  50

Number of employees in merged list = 6
Average salary in merged list = 54.5

When you hand in your code, we will also test it with other tests in addition to this one.


Handing in Your Code

Use hsp to hand in the entire directory containing your code. Do not submit the individual files, but rather submit the directory as a whole. For example, if I am sitting in the directory above cplspls, I would execute the following command:

hsp musicant CS395 cplspls

Good luck!