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
#include
#include
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 \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