Project 0: Warmup C++ Assignment

Assigned on Monday, 9/15.
Due electronically on Friday, 9/19, by 4:45 PM.


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 projects. 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. You may want to check out the functions strcmp, strlen, and strcpy in the string library.


Getting Started

First create a directory for storing all the code that you write associated with this course. If you have your own system by now, feel free to use it. Otherwise, create a directory called cs347. Then, create a new subdirectory called proj0 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 all the files from /Accounts/courses/cs347/proj0/ to your current directory.

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 ...
...
infile.close();
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);
...
outfile.close();

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, I will also test it with other tests in addition to this one. This means that you should try testing your code on other files that you create as well. Feel free to swap test files with each other. Finally, I will also run insure on your code to make sure that that your program exhibits no memory leaks or other bad memory behavior. You should run insure on your code before turning it in to see if you have memory issues.


Handing in Your Code

If you are working in a team (and please do!), only one of you should submit the code. Make sure that both of your names appear in program documentation at the top.

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 proj0, I would execute the following command:

hsp musicant CS347 proj0

Good luck!