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.