CSc 352: Assignment 8 solution


Original Work ?
Category: You will Instantly receive a download link for .ZIP solution file upon Payment


5/5 - (2 votes)

The purpose of this assignment is to do more involved work with pointers, linked lists, and memory allocation, to do a little work with command line arguments and reading from a file, and to learn to free all allocated memory.
General Requirements
1. Your C code should adhere to the coding standards for this class as listed in the Documents section on the Resources tab for Piazza. This includes protecting against buffer overflows whenever you read strings. 2. Your programs should indicate if they executed without any problems via their exit status, i.e., the value returned by the program when it terminates:
Execution Exit Status Normal, no problems 0 Error or problem encountered 1 3. Under bash you can check the exit status of a command or program cmd by typing the command “echo $?” immediately after the execution of cmd. A program can exit with status n by executing “exit(n)” anywhere in the program, or by having main() execute the statement “return(n)”. 4. Remember your code will be graded on lectura using a grading script. You should test your code on lectura using the diff command to compare your output to that of the example executable. 5. To get full points your code should compile without warnings or errors when the -Wall flag is set in gcc 6. Anytime you input a string you must protect against a buffer overflow. Review slides 82 – 87 of the basic_C deck. 7. You must check the return values to system calls that might fail due to not being able to allocate memory. (e.g. Check that malloc/calloc don’t return NULL) getline() is an exception to this rule. 8. Your code must run without errors using valgrind. 9. NEW REQUIREMENT, your program must free all allocated memory before exiting.

Example executables of the programs will be made available. You should copy and run these programs on lectura to test your program’s output and to answer questions you might have about how the program is supposed to operate. Our class has a home directory on lectura which is:
You all have access to this directory. The example programs will always be in the appropriate assignments/assg#/prob# subdirectory of this directory. They will have the same name as the assigned program with “ex” added to the start and the capitalization changed to maintain camelback. So, for example, if the assigned program is theBigProgram, then the example executable will be named exTheBigProgram. You should use the appropriate UNIX commands to copy these executables to your own directory.
Your programs will be graded by a script. This will include a timeout for all test cases. There must be a timeout or programs that don’t terminate will cause the grading script to never finish. This time out will never be less than 10 times the time it takes the example executable to complete with that test input and will usually be much longer than that. If your program takes an exceedingly long time to complete compared to the example code, you may want to think about how to clean up your implementation.
You will be required to include a Makefile with each program. Running the command:
make progName
should create the executable file progName, where progName is the program name listed for the problem. The gcc command in your Makefile must include the -Wall flag. Other than that, the command may have any flags you desire.
Submission Instructions
Your solutions are to be turned in on the host Since the assignment will be graded by a script, it is important you have the directory structure and the names of the files exact. Remember that UNIX is case sensitive, so make sure the capitalization is also correct. For all our assignments the directory structure should be as follows: The root directory will be named assg#, where # is the number of the current assignment. Inside that directory should be a subdirectory for each problem. These directories will be named prob# where # is the number of the problem within the assignment. Inside these directories should be any files required by the problem descriptions. For this assignment the directory structure should look like:

assg8 prob1 calls.c Makefile To submit your solutions, go to the directory containing your assg8 directory and use the following command:
turnin cs352f18-assg8 assg8

Problems prob1: calls
It’s time for some data mining! For this assignment you will write a C program in a file called calls.c and a Makefile which creates the executable calls that will open up a set of files (usually more than one), each of which has lines that are pairs of phone numbers (representing phone calls). You will record how many times each phone number has talked to each other phone number. After reading the files and creating a data structure, you will read queries from stdin. Each query will be a pair of phone numbers. If the two numbers have talked to each other, you will print how many times they talked (as indicated below). If they have not talked together, you will see if the numbers are connected through conversations. If they have, you will print the shortest path that connects the numbers. Details for this are below.
 Invocation:
Your program will be invoked with one or more file names specified as command line arguments:
calls inFile1 [ inFilei ] . . .
at least one inFile must be specified. It is followed by an optional number of additional files.
 Input:
All input for this program will consist of lines of two different phone numbers, where the phone numbers are specified by whitespace. The phone numbers should have the format, ddd-ddd-dddd where each d is a digit (0-9). So all input lines should look like:
ddd-ddd-dddd ddd-ddd-dddd
where the phone numbers are not identical and are separated by one or more spaces or tabs. Blank lines (lines containing only whitespace) are also allowed and should be ignored. A line in any other format should cause and error message to be printed to stderr and the line should be ignored.
 Program behavior:
Your program should open each of the specified input files for reading. If any of the files cannot be opened, you should print and error message to stderr and continue to the next given file. You will read the lines of phone numbers and use them to create a graph, much like you did in the last assignment. Here the phone numbers will be the vertices and the edges will represent a call between those numbers.
After all the files have been read, your program will read input from stdin. As with reading the files, it will read in lines, each of which should be a pair of phone numbers. These are queries. If the two numbers have talked your program will print out:
Talked n times
where n is the number of times the two numbers talked. Print this statement using:
printf(“Talked %d times\n”, num);
where num is an int variable containing the number of times the numbers talked.
If there was no direct call between the two numbers, then the program should check to see if they are connected indirectly. Two numbers are connected indirectly if there is a path of phone calls between them. For example suppose A did not talk to B, but A talked to C and C talked to B. In this case A is indirectly connected to B. If this is the case your program should print out the message:
Connected through n numbers
where n is the smallest number of phone numbers connecting the two numbers. Print this statement using the command:
printf(“Connected through %d numbers\n”, num);
where num is an int variable containing the smallest number of connecting numbers. The smallest number of connecting numbers is the number of phone numbers between the target phone numbers on the SHORTEST path connecting them. For example, if A talked to C and C talked to D, and D talked to B, then there are two connecting numbers on this path from A to B. However if A also talked to E and E talked to B, then there is only one connecting number on this path. In this case, the shorter path is A→E→B so the number 1 should be printed.
If there is no connecting path between the two numbers, you should print out the message:
Not connected
Note, please be careful of the format of these outputs. Check your output against the example executable using diff. I will use the –Z option on diff to grade these (meaning whitespace at the end of the line will be ignored), but I would hate for someone’s program to calculate the values correctly but lose all the points because of extra punctuation or misspelling.
If during the input of queries a phone number is entered that is not in the graph this should also be treated as a nonfatal error. (an error message printed to stderr and the input line ignored) It is also a nonfatal error if the two phone numbers are the same.

 Error Conditions:
Non-fatal errors: These should all be listed above. They include specifying an input file that can’t be opened for reading or a nonblank line that contains something other than two different phone numbers in correct format. It is also an error if a phone number that is not in the graph is queried. Remember to exit with a status of 1 if any error is encountered.
Fatal errors: If no input files are given as command line arguments. (Failure to get allocated memory is also a fatal error but not one that will be tested. Just make sure you check the return values of malloc, calloc, and strdup.)
 Restrictions:
The usual restrictions apply to this program. You may not allocate space for a large array to save the data structure. Instead you must implement the graph using linked lists.
 Data structure:
As in the last assignment, the data structure you should use for this program is an adjacency list to represent a graph. Note that in the last assignment the graph you created was directed, but in this assignment it should be undirected. If A talked to B, then B also talked to A. The easiest way to represent this is to add two edges, one from A and one from B, for every line you process.
Also note that vertices are added implicitly in this program. By this I mean that we don’t have a specific command to add phone numbers. Instead, if a line indicates that there was a call between A and B and A is not in the list of phone numbers it should be added. A last difference between this graph and the one you did for the last assignment is that you need to keep track of the number of calls made. To do this you will need to add a field to the struct you use to represent the graph’s edges to keep track of how many calls were made.
 Algorithm:
You need to find the shortest path connecting two nodes. For this a depth first search will not work. A depth first search finds if there is a path between two vertices, but not the shortest path. To find the shortest path, we will use a breadth first search. A depth first search recursively searches all the children of each vertex. A breadth first search puts all the children on a queue. This way all the children are searched before the grandchildren, etc. Here is the algorithm for a breadth first search:

//BFS does a breadth first search to find the shortest path //from Start to Target. It returns the size of that path if there //is a path from Start to Target and returns -1 otherwise int BFS(Start, Target) mark Start as queued set level of Start to 0 add Start to the queue
while queue is not empty do Take A from top of queue If A = Target, return A.level For all children C of A do if C not queued mark C as queued set level of C to A.level + 1 add C to queue
return -1 //If you get through loop without finding Target, //there is no path from Start to Target
Note that in C you will have to implement this queue with a linked list. Don’t forget to free it again after you’re done using it if applicable.
Please note: the level this algorithm gives you is the distance between two vertices. The program asks for the number of vertices between the two vertices, so the number you will output is the value returned – 1.

 Makefile:
In addition to your source file, you should submit a make file named Makefile that supports at least the following functionality:
make calls Compiles the C source code to create an executable named linked. The compiler options used should include -Wall.
Don’t forget that for this assignment you must free all your memory before exiting. Use valgrind to make sure all the memory is freed and that you have no memory errors.