Document 11560138

advertisement
CSCI-14 Final Project, due at midnight the last day of scheduled classes (the Friday before finals week),
late (-20%) by the start of the final exam. I accept no work of any type after the start of the final exam,
and I accept no other homework or labs after the last class day. (100 points)
Numeric addresses for computers on the original 32-bit Internet (32-bit IP addresses instead of the
current 64-bit ones) comprise four integers, separated by periods, in the form aa.bb.cc.dd, where aa, bb,
cc, and dd are decimal integers of no more than 3 digits. (This is not really true, but you may assume that
it is for this program). Machines also have a local nickname, such as “pizza”. For this program,
nicknames will be at most 15 lower-case letters (with no imbedded spaces, upper-case letters, digits or
other non-alphabetic characters, again, not always true in the real world). Assume that machines on the
same local network (sub-net) always share the same two first numbers (again, this is not always true, but
it's close enough). Create a struct ADDRESS_TYPE to hold the 4 integers of the IP address and a string
for the machine name. You may use either a C++ string object or a C-string (an array of least 16 chars,
the one extra being for the trailing NUL).
Write a program to use direct file input to read a list of IP addresses and associated names. The last entry
in the file will be a machine with 0.0.0.0 as its address and the name "none". You may assume there will
be no more than 200 lines in the file and that the file data are correct. Set up an array of 200
ADDRESS_TYPE structs to hold the entries.
Use direct file output for all output. The output is as follows (in this order):





a list of all groups of two or more machines belonging to the same sub-network (the first two
numbers in their IP address are the same) printing the machine names only. The machines in each of
the groups must be listed in the same order as they appear in the input file.
the file contents (unsorted)
the file contents (sorted by machine name)
the file contents (sorted by IP address)
the number of groups of machines in the file, the number of machines in the largest group and the
number of machines in the smallest group (not counting single machines) with appropriate text
Identify each of the output sections by printing a line telling me what's next before printing the output in
the section. In the first output section, identify the machines in each group by their nicknames only, and,
once a machine name is printed as part of a group, do not print it again as a part of another group.
You will need (at least) the following functions:
 A bool ReadRecord(ADDRESS_TYPE &a, istream &in) function to load a SINGLE line
from the input file into ONE single machine structure (return a code indicating if it just read 0.0.0.0
or not). You MAY NOT pass in the array of ADDRESS_TYPE for this, it MUST read one record
only. ReadRecord() may return an int instead of a bool. This will run in a loop reading
elements into your array until it tells you that it read the 0.0.0.0 record.
 A void PrintRecord(ADDRESS_TYPE a, ostream &out, bool NameOnly)
function to print either the IP address and name of a single ADDRESS_TYPE struct, or the name
only if the NameOnly flag is true. The ADDRESS_TYPE may be passed by reference. Again, you
MAY NOT pass in the array of ADDRESS_TYPE for this.
You will need other functions as well. Use a good modular design, with functions to do the separate
tasks.
A sample data file might look like this:
111.22.3.44
555.66.7.88
111.22.5.66
555.66.11.24
123.45.67.89
12.34.56.78
555.66.9.10
0.0.0.0
none
platte
wabash
green
homer
loner
pizza
ulysses
For this file, you will print out the following groups of machines on the same sub-nets:
platte
green
---------------- // separate each group with a line of 15-20 dashes or tildes
wabash
homer
ulysses
Prompt for the input and output file names and hold them in C-strings, NOT C++ string objects. DO
NOT HARD-CODE THE FILE NAMES. The sample test file above is on my Web site as hosts.txt. Test
with it, as well as files several of your own making. Include a test where there are no groups, (several
machines with no two IP addresses starting with the same two values), no machines before the sentinel
(the first line is 0.0.0.0 none), and some tests with large groups. For the large group tests, create files of
100 or more machines with at least two or three fairly big groups in the file. Include tests where all the
machines in a group are contiguous and tests where the groups are interleaved.
Hints:
Use a second array of flags (bools or ints, initially all false) to track whether or not this machine name
has been printed yet, and set the flag to true when you print the corresponding machine name. Associate
the flag with the machine record by using the same index into both arrays to mean the same machine.
Use an outer loop to pass through the array of machines for a machine that has not been printed yet.
When you find one, use a separate inner loop to look for a match to the outer loop's element's sub-net
address (aa.bb). If you find a match, print the separator and both names, flip the corresponding 'printed'
flags, then continue to look for more matching I.P. groups in the rest of the array of machines. When
your inner loop stops, go on to the next element in the outer loop. Collect statistics for the number of
groups and the largest and smallest group while you are printing.
After you print the groups, use a loop to print the elements in their original sequence. Then use any
reasonable sorting algorithm [O(n2) is fine] to sort the list by machine name, and print the list again.
Then use any sorting algorithm to sort the list by IP address, and print the list again. Since you will print
the data in the array three times, use a function to do this job. You have algorithms from class (e.g.,
ripple sort, bubble sort, selection sort) for sorting.
One of your sorting algorithms is going to be sorting on IP numbers, which are split into four separate
values in your struct. You can use a double (why not an int?), and put the address parts into the double
multiplied by appropriate powers of 10 to get a single comparable key. For example, with only two
numbers in a key, 12.45 becomes (12*1000) + 45 = 12045, which can be compared with another single
value. The other sorting algorithm will sort on the machine nicknames. You can use strcmp() from the
<cstring> library to compare two C-strings. I’ll discuss how to do this in class. Alternatively, you may
compare two C++ string objects (use the <string> library) directly with >, <, etc.
If you think about the sorting problem carefully, you will see that you can do these two sorts with a single
sort function -- it just needs to know how to compare the ADDRESS_TYPE structs in order to sort
correctly.
0.0.0.0 is an address, the last one in the input file. You will need to sort it into the first position before
printing the list sorted by IP addresses. However, you may assume it will never be part of a group of
machines on the same subnet.
This program is noticeably longer than anything else in this course, but it is not particularly complex.
The only tricky part is printing the groups and collecting the statistics. Expect several hours of effort to
make it work.
Designing the algorithm for the entire problem will be critical before you start to write code.
The highest level of your top-down design might look like this:
initialize
open files and test for open successful
read data from file into array of structs
find groups & print them by name only, collect group statistics for later
print table of machine addresses and names (unsorted)
sort table of machine names by name
print table of machine addresses and names
sort table of machine names by address
print table of machine addresses and names
print group statistics
close files
Remember, per the syllabus:
You must turn in the final programming project (essentially working) to make a
grade higher than C in the course.
Download