HC Search (File I/O and Malloc Example Using Functions)
HC Search
File I/O and Malloc Example Using Functions

/* This program may or may not meet your coding standards. * Please don't use it as a guide for your program's format. * * HC Search is a program which accepts two command line * arguements. The first arguement should be the name of the * user's input file; the second the name of the output file. * the format of the file is as follows: * - an int (representing the number of "cities" in the file) * on the first line followed by floating point pairs separated by * a comma (the first number represents the city's x-coordinate * the second its y-cooridinate). * * Program written by Margot McKinney in October 2000. * Last edited 17 April 2001. */ #include <stdio.h> #include <stdlib.h> #include <math.h> typedef struct coords { int num; /* City's number (acts as a name) */ float x; float y; } COORDS; void AllocateCOORDS(int num, COORDS **coordsPtr); float HCSearch(COORDS *cities, int num); void main(int argc, char *argv[]) { int i, num; float totalDist; COORDS *cities; FILE *ifp, *ofp; /* Check the number of arguements provided by the user. If * there are not three, print msg and exit. */ if(argc != 3) { fprintf(stderr, "Usage: a.out <inputFile> <outputFile>\n"); exit(-3); } /* Attempt to open the inputFile stored in as the first arguement, * argc[1]. If unopenable, print msg and exit. */ ifp = fopen(argv[1], "r") ; if (ifp == NULL) { fprintf (stderr, "Error opening %s.\n", argv[1]); exit (-1); } /* Read in the first number in the open file. Call * AllocateCOORDS function to allocate memory for the array of * cities. Checking is done in the function. */ fscanf(ifp, "%d", &num) ; AllocateCOORDS(num, &cities); /* Read in each of the cites from the file and assign them * into the array. Give each city a number (in the order they * are read here) and print the city to the screen. */ for( i = 0; i < num; i++) { fscanf(ifp, "%f, %f", &cities[i].x, &cities[i].y); cities[i].num = i + 1; } fclose(ifp) ; /* Close the user's file. */ totalDist = HCSearch(cities, num); ofp = fopen(argv[2], "w"); if(ofp == NULL) { fprintf (stderr, "Error opening %s.\n", argv[2]); exit (-1); } fprintf(ofp, "\n\nStarting with City 1... "); /* Print the results to the file specified in the 2nd arguement */ for( i = 0; i < num; i++) { fprintf(ofp, "\n\tVisit to City %d (%.2f, %.2f)", cities[i].num, cities[i].x, cities[i].y); if( i < num - 1 ) { fprintf(ofp, " followed by"); } } fprintf(ofp, "\nTotal Distance Traveled: %f\n", totalDist); fclose(ofp); free(cities); /* Free the memory allocated for cities. */ } /* the AllocateCOORDS() function takes two arguements. The first * is the number of COORDS it will be allocating memory for. The * second is the address of the pointer in main which will point * to the memory allocated here. */ void AllocateCOORDS(int num, COORDS **coordsPtr) { *coordsPtr = (COORDS *)(malloc(sizeof(COORDS) * num)); if (*coordsPtr == NULL){ fprintf (stderr, "Error allocating memory.\n"); exit (-2); } } /* the HCSearch() function takes an array of COORDS and the number * of elements in the array. Then it runs a Hill-Climbing Search * on the contents of the array and returns the total distance * traveled at the end of the Hamilton Circuit. */ float HCSearch(COORDS *cities, int num) { float leastDist, currDist, totalDist = 0, xDist, yDist; int curr, i; COORDS *cityPtr, temp; /* Assign curr 0 becuse no visits have been made. */ curr = 0; /* While there are still unvisited cities. */ while( curr < num - 1 ) { /* Initialize leastDist to 10 - no cities are this far apart. */ leastDist = 10; cityPtr = &cities[curr]; for( i = curr + 1; i < num; i++) { /* Compute the distance between the curr city and each of the * remaining cities. */ xDist = cities[curr].x - cities[i].x; yDist = cities[curr].y - cities[i].y; currDist = sqrt((xDist * xDist) + (yDist * yDist)); /* If currDist is 0, we are visiting ourselves. Continue * with the next iteration of the loop. */ if( currDist == 0 ) { continue; } /* If the leastDist is less than the currDist then assign the * currDist to the least and point the the current city, since * it is now the closeest. */ if( leastDist > currDist ) { leastDist = currDist; cityPtr = &cities[i]; } } /* Increment curr since we are visiting another city. */ curr++; /* Swap the closest city (from the previous) into the current * current position. */ temp = cities[curr]; cities[curr] = *cityPtr; *cityPtr = temp; /* Add the distance between the two cities to totalDist. */ totalDist += leastDist; } /* Compute the distance from the last city visited to the first * in order to complete our tour of all the cities. */ xDist = cities[0].x - cities[num - 1].x; yDist = cities[0].y - cities[num - 1].y; totalDist += sqrt((xDist * xDist) + (yDist * yDist)); return(totalDist); }


Main Page