..."But using string as the index becomes difficult."
..."I want to record the distance between two cities"...
You cannot use a string as an array index, but you can associate a specific array index with a particular string using a combination of an enum
(array index) and const char array
. The following address the two stated issues above by illustrating how a struct
, enum
and const char arrays
may be used in calulating distances between city locations.
//from Google:
//Longest city name: Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch
#define MAX_NAME 60 //59+1
#define earthRadiusKm 6371.0
#define PI 3.14159265359
enum {
LAT,
LON
};
enum {
NEW_YORK,
WASHINGTON,
MIAMI,
MAX_CITIES
};
typedef struct {
char sCity[MAX_NAME];
double lat;
double lon;
}CITY_LOC;
// Note:
// Normally the following two items would be accessed from a lookup
// table, or database, but for purposes of illustration, will
// include a very abbreviated collection of values for city strings
// and latitude/longitude values here:
const char cities[MAX_CITIES][MAX_NAME] = {"New York", "Washington", "Miami"};
double lat_lon[MAX_CITIES][2] = {{40.730610, -73.935242},
{38.889931, -77.009003},
{25.761681, -80.191788}};
double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d);
double deg2rad(double deg);
double rad2deg(double rad);
int GetCityIndexFromString(char *city);
/// enter two city names
/// use double quotes if city name include spaces. eg. "New York"
int main(int argc, char *argv[])
{
int i, j;
double MAP[MAX_CITIES][MAX_CITIES] = {0};
CITY_LOC cLoc[MAX_CITIES] = {0};
if(argc != 3)
{
printf("Usage: %s <city1> <city2>\nExiting", argv[0]);
getchar();
return 0;
}
//populate struct
for(i=0;i<MAX_CITIES;i++)
{
strcpy(cLoc[i].sCity, cities[i]);
cLoc[i].lat = lat_lon[i][LAT];
cLoc[i].lon = lat_lon[i][LON];
}
//calculate distances between all cities
for(i=NEW_YORK;i<MAX_CITIES;i++)
{
for(j=NEW_YORK;j<MAX_CITIES;j++)
{
MAP[i][j] = distanceEarth(cLoc[i].lat, cLoc[i].lon, cLoc[j].lat, cLoc[j].lon);
}
}
//distance in kilometers between requested cities
int city1 = GetCityIndexFromString(argv[1]);
int city2 = GetCityIndexFromString(argv[2]);
double distance = MAP[city1][city2];
return 0;
}
int GetCityIndexFromString(char *city)
{
int i;
for(i=0;i<MAX_CITIES;i++)
{
if(stricmp(city,cities[i]) == 0)
{
return i;
}
}
return -1;
}
double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d) {
double lat1r, lon1r, lat2r, lon2r, u, v;
lat1r = deg2rad(lat1d);
lon1r = deg2rad(lon1d);
lat2r = deg2rad(lat2d);
lon2r = deg2rad(lon2d);
u = sin((lat2r - lat1r)/2);
v = sin((lon2r - lon1r)/2);
return 2.0 * earthRadiusKm * asin(sqrt(u * u + cos(lat1r) * cos(lat2r) * v * v));
}
// This function converts decimal degrees to radians
double deg2rad(double deg) {
return (deg * PI / 180);
}
// This function converts radians to decimal degrees
double rad2deg(double rad) {
return (rad * 180 / PI);
}
Where credit for distanceEarth()
goes to:
double distanceEarth(double lat1d, double lon1d, double lat2d, double lon2d)