# Need assistance with Structures.

• 02-18-2013
aquari
Need assistance with Structures.
Hello,

I'm working on a lab assignment and in need of assistance related to Structures. The next step I am trying to figure out is how to calculate the distance from one airport (SFO) to all other cities using the Haversine Formula.

So far, I have:
1. Read the data file "Coordinates.csv".
a. Stored the city name in the 'city' field.
b. Stored the city code in the 'code' field.
c. Stored the latitude in the 'latitude' field.
d. Stored the longitude in the 'longitude' field.

The Coordinates.csv file contains:

Seattle,SEA,47.75,122.3
San Francisco,SFO,37.75,122.68
Los Angeles,LAX,33.93,118.4
Dallas/Fort Worth,DFW,32.73,96.97
Orlando,MCO,28.43,81.32
Atlanta,ATL,33.65,84.42
Salt Lake City,SLC,40.79,111.98
LaGardia,LGA,40.77,73.9
Chicago,ORD,41.98,87.9
Denver,DEN,39.75,104.87

2. Made a dynamic array using malloc, large enough to hold all of the airport information. using pointer notation when accessing the data in the Coordinate structures.

Code:

```#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> const double PI = 3.14159; // Global Declarations typedef struct Coordinates {     char* city;     char* code;     double latitude;     double longitude; }Coordinates; // Function Declarations int ReadFile (char* filename, char*** strings); void GetCoordinates (struct Coordinates** coordinateslist, char** data, int count); double Haversine (double dlatitude1, double dlongitude1, double dlatitude2, double dlongitude2, double radius); void main() { // Local Declarations     char** matrix = NULL;     struct Coordinates* coordinates = NULL;     int count = ReadFile("C:\\Coordinates.csv", &matrix);     int index = 0;     double radius = 3959;     double dlatitude1;     double dlongitude1;     double dlatitude2;     double dlongitude2;     double res; // Statements     if (count > 0)     {         GetCoordinates (&coordinates,matrix,count);         for (index = 0; index < count; index++)           printf("City: %s\nCode: %s\nLatitude: %.2f\nLongitude: %.2f\n\n", (coordinates+index)->city, (coordinates+index)->code,                   (coordinates+index)->latitude, (coordinates+index)->longitude);     }     return; } int ReadFile (char* filename, char*** strings) {     FILE* fp = fopen(filename,"r");     char temp[128];     int count = 0;     while (!feof(fp))     {         if (fgets(temp,128,fp) != NULL)             count++;     }     fseek(fp,0,SEEK_SET);     *strings = (char**)malloc(sizeof(char*)*count);     count = 0;     while (!feof(fp))     {         if (fgets(temp,128,fp) != NULL)         {             *((*strings)+count) = (char*)malloc(strlen(temp)+1);             strcpy(*((*strings)+count),temp);             count++;         }     }     fclose(fp);     return count; } void GetCoordinates(struct Coordinates** coordinateslist, char** data, int count) { // Local Declarations     char temp[32];     char* ptr = NULL;     int index = 0; // Statements     *coordinateslist = (struct Coordinates*)malloc(sizeof(struct Coordinates)*count);     for (index=0; index<count; index++)     {         strcpy(temp,data[index]);         ptr = strtok(temp,",");         ((*coordinateslist)+index)->city = (char*)malloc(strlen(ptr)+1);         strcpy(((*coordinateslist)+index)->city,ptr);         ptr = strtok(NULL,",");         *(ptr+strlen(ptr)) = NULL;         ((*coordinateslist)+index)->code = (char*)malloc(strlen(ptr));         strcpy(((*coordinateslist)+index)->code,ptr);         ptr = strtok(NULL,",");         *(ptr+strlen(ptr)) = NULL;         ((*coordinateslist)+index)->latitude = atof(ptr);         ptr = strtok(NULL,",");         *(ptr+strlen(ptr)) = NULL;         ((*coordinateslist)+index)->longitude = atof(ptr);     } } double Radians(double value) { double radians = value * PI / 180.0; return radians; } double Haversine (double dlatitude1, double dlongitude1, double dlatitude2, double dlongitude2, double radius) {     double dLatitude = Radians(dlatitude2-dlatitude1);     double dLongitude = Radians(dlongitude2-dlongitude1);     double nA = pow ( sin(dLatitude/2.0), 2.0 ) + cos(Radians(dlatitude1)) * cos(Radians(dlatitude2)) * pow ( sin(dLongitude/2.0), 2.0 );     double nC = 2.0 * atan2( sqrt(nA), sqrt( 1.0 - nA ));     double distance = radius * nC;     return distance; }```
I'm really not too sure where to start on calculating the distance but my assumption is that I need to point values from latitude and longitude to dlatitude1-2 and dlongitude1-2.

Any feedback would be great as I have been stuck on this for several hours now. Thank you.
• 02-18-2013
It's confusing. The title says needs help with structures, but you don't need help with structures. You need help with the calculations, say you don't know where to begin, but you have an entire function already for the calculations.

Can you narrow this down - what EXACTLY is it that isn't working as it should. Say you feed it the data you listed above, what calculations are coming out wrong. I need a starting place - something definite.

If you would include the formula you're using for the distance calculation, that would be a good thing to add. I certainly don't have it memorized.
• 02-18-2013
Salem
> I'm really not too sure where to start on calculating the distance but my assumption is that I need to point values from latitude and longitude to dlatitude1-2 and dlongitude1-2.
I think you've got pointers on the brain.

Haversine is called with two latlongs and a radius (all by value)

So
dist = Haversine( coordinates[0].latitude, coordinates[0].longitude, coordinates[1].latitude, coordinates[1].longitude, radius );

> while (!feof(fp))
You could condense this code to be
while ( fgets(temp,128,fp) != NULL )

> *((*strings)+count) = (char*)malloc(strlen(temp)+1);
> strcpy(*((*strings)+count),temp);
You do this in a number of places (and get it wrong in one of them).
Consider a small function to allocate space and copy the string, returning the pointer to the newly allocated and copy string.

You should also stop casting the return result of malloc in C programs.
If (by removing the cast) you get "can't convert void* to T*" warnings, then you should stop using a C++ compiler to compile your C code.

> void main()
Nope - main returns int

At some point, you'll need to call free() on all the things you malloc'ed.
• 02-19-2013
aquari
Sorry about that. Totally should've included the Haversine formula. Here it is:

Code:

```const double PI = 3.14159; double Radians(double value) { double radians = value * PI / 180.0; return radians; } double Haversine( double dlatitude1, double dlongitude1, double dlatitude2, double dlongitude2, double radius ) { double dLatitude = Radians(dlatitude2-dlatitude1); double dLongitude = Radians(dlongitude2-dlongitude1); double  nA = pow ( sin(dLatitude/2.0), 2.0 ) + cos(Radians(dlatitude1)) *  cos(Radians(dlatitude2)) * pow ( sin(dLongitude/2.0), 2.0 ); double nC = 2.0 * atan2( sqrt(nA), sqrt( 1.0 - nA )); double distance = radius * nC; return distance; }```
I'm basically looking to understand how to use the Haversine formula to calculate the distances. I'm able to print out all airports and their coordinates from the data file at this point. Just not too sure how to use the formula and print out the total distance between SFO and all other airports.

I placed the Haversine formula at the bottom of the code and not too sure where to go from there.

Thanks for the feedback Salem I'll give that a try. Really appreciate the feedback.
• 02-19-2013
aquari
I went with Salem suggestion and it works. Thanks. Now the issue I am having is that the distance prints the same number for each airport distance. My output looks like this:

SFO to SEA = 670.52 miles
SFO to SFO = 670.52 miles
SFO to LAX = 670.52 miles
SFO to DFW = 670.52 miles
SFO to MCO = 670.52 miles
SFO to ATL = 670.52 miles
SFO to SLC = 670.52 miles
SFO to LGA = 670.52 miles
SFO to ORD = 670.52 miles
SFO to DEN = 670.52 miles

Code:

```// Local Declarations double dist; // Statements { dist = Haversine(coordinates[1].latitude, coordinates[1].longitude, coordinates[i].latitude, coordinates[i].longitude, radius);         for (i=0; i<count; i++)             printf("%s to %s = %.2f miles\n", coordinates[1].code, coordinates[i].code, dist);     return; }```
I'm having difficulty with the for loop and printing the values that correspond to the correct values for the distances.
• 02-19-2013
Salem
You need the calculation inside the loop.