This should be a very easy project just to remind you of some things that should already be familiar from CISC181, but might be rusty if it has "been a while". We'll move on to more advanced material quickly, e.g. linked lists,etc. Don't get fancy in this project! Keep it simple!
Here's some things you will need to know though. If you aren't sure of any of these topics, come see me SOON!
There is nothing to turn in for this step.
Look at the files in the directory http://www.udel.edu/CIS/220/pconrad/06J/work/proj/proj1. (You can also find these files on strauss in the directory /www/htdocs/CIS/220/pconrad/06J/work/proj/proj1). You'll see three data files containing fictional data called:
elevenNames.txt fiveNames.txt tenNames.txt
These three files contain data about fictional people, in the following comma separated format:
ssn,lastName,firstName,sex,city,state,zip,phone
For example
> more fiveNames.txt 678487999,Clements,Barry,M,Green Bay,WI,54304,(414)872-4415 682844351,Lasley,Johnny,M,Auburn,WA,98002,(206)776-6826 562977072,Brown,Deidre,F,Atlanta,GA,30350,(404)279-9326 762012803,Lake,Dario,M,Brooklyn,NY,11226,(718)771-8703 593966803,Hanson,Patricia,F,Colorado City,TX,79512,(915)228-7086 >
Your job in this step is to look at these data files and think about how you would represent each line in this file as a C++ object. That is, if you were going to have a class called Person_C
to represent one line of this data file, what would be the private data members? What would the member functions be?
Here's how the rest of the project will proceed:
Detailed instructions will follow below. You should complete at least one step every day in order to stay on schedule and not fall behind in the course!
Oh one note—before going on, you should create a cisc220 directory under your home directory, and a proj1 directory under that. (Hopefully, you feel insulted that I'm even telling you this, because by now, you'd just automatically do that without even being told. In fact, if you already did it before even reading this, that's a very good sign!)
One tip that you might not have picked up before: you can create the directories and move into them in just two steps, by putting the -p flag on the mkdir command:
mkdir -p ~/cisc220/proj1
cd ~/cisc220/proj1
The -p
means that the intermediate directory cisc220
will be automatically created if it doesn't already exist.
Now copy the files into your current directory with:
cp /www/htdocs/CIS/220/pconrad/06J/work/proj/proj1/*.txt .
In a few days, I'll show you the program I wrote to generate this random data—it's actually pretty cool. It generates random data files with
Why the mismatch—1990 Census data for names, and 2000 data for population? It's what I could get. But that's beside the point. Let's get on with this project!
A few reminders about class definitions:
Some requirements for this assignment:
Include only constructor that will take (as its only formal paramter) the following:
char * const inputLine
The C-string inputLine
will be one line from the data file, e.g.
678487999,Clements,Barry,M,Green Bay,WI,54304,(414)872-4415
The constructor should use strtok()
to parse the line into the various fields, and then store the data into those fields in the newly constructed Person_C object.
For firstName
, lastName
, and city
, use variable length C-strings (not C++ strings), allocated from the heap as dynamic memory. (We'll start using C++ style strings soon, but I need to make sure you know how to use C-strings, and understand heap vs. stack first!) (p. 151-154 in Malik covers dynamic arrays, which is pretty much similar to allocating a C-string from the heap, except that with C-strings, you have to remember to allocate space for the null terminator as well.) As you may remember, that means that in the private data member section, you declare these as type char *
variables, not as arrays of char.
For ssn
, you may use either an int (since nine digits will fit in an 32-bit int
), or an array of char
(fixed size, or variable size).
For the 2-char state
abbreviation, use a fixed length char array (containing a C-string). How big does it need to be?
For phoneNumber
, you may either use a variable length C-string or a fixed length char array (containing a C-string).
Before going on to Step 2, you can try compiling your .h file by creating a dummy main program like the one shown here. This file is also on the web site in a file called proj1/dummyMain.cc. The idea is that while you can't compile the file person.h directly to check for syntax, you can compile "dummyMain.cc" and see if it compiles. If there are errors in person.h, they'll show up when you compile dummyMain.cc.
// dummyMain.cc P. Conrad for CISC220, 06J // Illustrate how to check a .h file for correct syntax #include "person.h" int main(void) { return 0; }
Now write the file person.cc containing the member functions for the Person_C class. Remember the following general tips:
Person_C
) and the binary scope resolution operator (::
)right before the name of the function. For example:const char * const Person_C::getName() const { return name; }
atoi()
to convert it from string to integer. For variable length C-strings, firstallocate new space on the heap for each data value, then use strcpy() to copy the data in. For example:
char *theSSNString = strtok(inputLine,","); ssn = atoi(theSSNString); ... char *theFirstName = strtok(NULL,","); firstName = new char (strlen(theFirstName)+1); strcpy(firstName, theFirstName);
If you are new to Makefiles, or rusty, consult the Appendix on Makefiles in your Andersen textbook for a tutorial, or come see me for help. We'll also review a bit during lecture.
A few things to remember:
Makefiles should start with a comment, and in makefiles, comments start with #
, not with //
Near the top, define with C++ compiler you are going to use with either: CCC=g++
or CCC=CC
Near the top, define an "all
" rule that lists the binaries you are creating. For now, that rule can be all: dummyMain
Rules start with a target, followed by a colon, followed by a list of files the target depends on. The next line (or lines) contain the actions that are carried out to "make" the target from the source files. Those action lines must start with exactly one tab, not with spaces, or a combination of spaces and tabs. The command cat -t Makefile
will make tabs visible as ^I
characters.
Rules to create .o files from .cc files generally have actions that start with ${CCC} -c
Rules to link executables from .o files generally have actions such as ${CCC} file1.o file2.o file3.o
-o $@
You generally name the executable after whichever .cc file has the definition of the main()
function in it.
Near the bottom, there should be a clean rule that deletes all binaries, .o
files, the file a.out
, and the file core
.
To test your Makefile, just type "make" at the command line. Also try "make clean" followed by "make". It should compile your code.
Some specific requirements for your main program:
Your main program should not do any interaction with the user. It should take a filename from the command line argument. As a reminder, this means that instead of: int main(void)
you'll use int main(int argc, char *argv[])
In the main program, check that argc
is the appropriate value for exactly one command line argument after the program name. (If you aren't sure about this, ask your instructor to review this concept in lecture, or ask during office hours.) Then use argv[1]
with the ifstream
constructor to open the input file. Check that the input file opened successfully—if it didn't, then print an error message on cerr
, and call exit()
with a status code of 1
.
In the main program, declare a integer constant called arraySize
and set its value to 10
. This value is specific and is a requirement of the assignment. The reason for this value is that the sample data files contain 5, 10 and 11 records each.
In the main program, declare an array as follows:
Person_C *people[arraySize] = {NULL};
Note that this array is of Person_C *
pointers, not an array of Person_C
objects. The array containing the pointer values will be on the stack, but the objects themselves will be on the heap. The syntax {NULL}
initializes all of the pointers to zero, i.e. NULL
. Also declare a int
variable count
and initialize it to zero—this variable will count the number of people actually stored in the array (initially, none.)
getline()
member function of ifstream to read all the data from the file. For each record read, use the Person_C constructor to conver the data read in by getline() into a new Person_C, with code like this:people[count] = new Person_C(inputLine);
Remember to increment count after you store new data into the array, not before! This is because the first record goes into people[0]
, not people[1]
.arraySize
lines of data, an error message is printed, and the program is halted immediately. The error message should indicate that the size of the input file is too large for the capabilities of the program, and it should also print what the maximum size file is. This is why I've given you three files—one with five lines of data, one with ten lines of data, and one with eleven. Your program should work correctly for the case of 5 and 10 lines, and produce an error message for the one with eleven lines.setw()
stream manipulator to make the output look nice. For now, you only have to print out the data in the order that you read it in from the file. In a future assignment, you'll add the capability to sort the array in various ways, but for now don't do it! We are going to talk about a few things related to sorting before we get into that, and if you start now without that information, you are likely to head down a blind alley. If you want to experiment, fine—I encourage that!—but do it after you've submitted a working simple version of a completed project.
For that matter, for the version you turn in for credit, don't do anything else that isn't specifically required by the assignment without asking first. In this real world, such "extra features" are often not appreciated, and can create real problems for customers when the interact in unexpected ways with other parts of a system. This is such a problem that there's even a buzzword for this: YAGNI. Look it up in a search engine!
That doesn't mean that I don't want you to be creative and stretch your wings as a programmer. If you want to do an "above and beyond" submission separately from your main submission for credit, just to play around and learn new stuff, let me know. We'll work something out.
Don't start this step until you have finished all your programming, and are ready to submit your work.
However, if you are new to the process of creating a tar file, don't wait until the last minute—you may need some time to figure this part out.
A "tar" file is a file that allows an entire collection of files to wrapped up into a single file.
You may be familiar with "zip" files, which are often used to distribute software packages on Windows PCs, or "sit" files which are used to distribute files on Macintosh computers. The files known as "tar" files are similar.
(A bit of history: "tar" originally stood for "tape archive". It's still the format sometimes used to store backup files on tape drives.)
To create a tar file from your proj1 files, follow these steps:
tar -cvf proj1.tar proj1This command says "create a new tar file named
proj1.tar
" -cvf proj1.tar
part) and put all the files from the subdirectory proj1
into it.~/cisc220/test
, and cd
into it.proj1.tar
file into that directory. Then use the command: tar -xvf proj1.tarThis command should expand the
proj1.tar
file, and leave you with a new subdirectory ~/cisc220/test/proj1
that contains all of the files from your real proj1 directory. Change your working directory into that test directory and use the "ls
" command to list your files. Make sure everything looks correct, because this is what your TA and instructor will see after you submit. So, try the "make clean" and "make all" rules to make sure everything still works properly. If so, then you can now submit "proj1.tar" along with a script (proj1.txt) as your submission to WebCT.If you are unfamiliar with using the "script" program on strauss (e.g. because you took CISC181 somewhere other than UD, or because its been a while), ask your instructor to walk you through it.
Your final submission should include your .h files and .cc files for your Person_C class, a Makefile, and your main program proj1.cc. It's ok if you also include dummyMain.cc, but that isn't required.
Make a script showing a clean compile (make clean; make all) and demonstration run(s) of your program on all three data files (fiveNames.txt, tenNames.txt and elevenNames.txt) along with cat and ls commands where needed to show input and output files.
You always are required to submit the script file to WebCT separately even if it is included in your tar file.
You should also submit a tar file containing your code, Makefile, and input files. (do a Make clean first; points deducted if you don't). Your tar file can contain your script file, but it doesn't have to.
Some strict results regarding submissions: